0

以下是名为 df 的格式化数据框。

Company     Category    Margin     Ranking
SBI             BK      34.5       1
PNB             BK      39.5       2
UCO BANK        BK      39.9       3 
BANK            BK      41.3       4
INDIAN BANK     BK      42.3       5
DENA BANK       BK      44.5       6
VIJAYA BANK     BK      44.5       7
UNION BANK      BK      47.6       8
CENTRAL BANK    BK      49.8       9
INFOSYS         IT      5.6        1
HCL TECH        IT      5.9        2
TCS             IT      6.9        3
CMC             IT      12.6       4
TECHMAHINDRA    IT      12.6       5
COGNIZANT       IT      15.8       6
IGATE           IT      22.4       7
WIPRO           IT      22.9       8
HEXAWARE        IT      34.8       9
MAHINDRA SATYAM IT      34.8       10
DR. REDDYS      PH      14.5       1
SUN PHARMA      PH      19.2       2
CIPLA           PH      23.9       3
LUPIN           PH      23.9       4
DIVIS LABS      PH      29         5

我想编写一个函数rankCompany(),它接受 2 个参数(i)一个向量(一组类别)和(ii)一个等级(整数)作为 2 个参数。

函数的输出 - Data.Frame ( df.out )

df.out 的内容

具有与指定排名相匹配的公司名称、类别和利润。
如果任何类别没有与给定排名匹配的公司,则应在该列下返回。

下面是测试该功能的示例代码。

测试#1

catg <- c("BK", "IT", "PH")
rankCompany(catg, 2)
    Company          Category        Margin
BK  PNB              BK              39.5
IT  HCLTECH          IT              5.9
PH  SUN PHARMA       PH              19.2

测试#2

catg <- c("BK", "IT", "PH")
rankCompany(catg, 7)
    Company          Category        Margin
BK  VIJAYA BANK      BK              44.5
IT  IGATE            IT              22.4
PH  <NA>             PH              <NA>  

测试#3

catg <- c("BK", "IT", "PH", "EG")
rankCompany(catg, 10)
    Company          Category        Margin
BK  <NA>             BK              <NA>
IT  MAHINDRA SATYAM  IT              34.8
PH  <NA>             PH              <NA>
EG  <NA>             EG              <NA>

有什么简单的方法可以完成这项工作吗?

4

2 回答 2

7

merge将是您应该研究的功能。这是一个示例函数:

rankCompany <- function(inDF = mydf, catg, ranking) {
  merge(inDF, data.frame(Category = catg, Ranking = ranking), all.y = TRUE)
}

这是您的“测试用例”。

test1 <- c("BK", "IT", "PH")
rankCompany(catg = test1, ranking = 2)
#   Category Ranking    Company Margin
# 1       BK       2        PNB   39.5
# 2       IT       2   HCL TECH    5.9
# 3       PH       2 SUN PHARMA   19.2

test2 <- c("BK", "IT", "PH")
rankCompany(catg = test2, ranking = 7)
#   Category Ranking     Company Margin
# 1       BK       7 VIJAYA BANK   44.5
# 2       IT       7       IGATE   22.4
# 3       PH       7        <NA>     NA

test3 <- c("BK", "IT", "PH", "EG")
rankCompany(catg = test3, ranking = 10)
#   Category Ranking         Company Margin
# 1       BK      10            <NA>     NA
# 2       IT      10 MAHINDRA SATYAM   34.8
# 3       PH      10            <NA>     NA
# 4       EG      10            <NA>     NA

更新

看到你想要的“最差”后,这里有一个比你的函数更好的替代方法,原因有几个(例如,没有将值硬编码到函数体中作为开始)。

rankCompany <- function(inDF = mydf, catg, ranking) {
  if (ranking == "worst") {
    do.call(rbind, by(inDF, catg, tail, 1))
  } else {
    merge(inDF, data.frame(Category = catg, Ranking = ranking), all.y = TRUE)
  }
}

rankCompany(catg = mydf$Category, ranking = "worst")
#            Company Category Margin Ranking
# BK    CENTRAL BANK       BK   49.8       9
# IT MAHINDRA SATYAM       IT   34.8      10
# PH      DIVIS LABS       PH   29.0       5

为了以后方便他人,请分享dput您的数据,以便他们轻松复制。它应该看起来像这样:

mydf <- structure(list(Company = structure(c(17L, 16L, 21L, 1L, 12L, 
    6L, 23L, 22L, 2L, 13L, 9L, 19L, 4L, 20L, 5L, 11L, 24L, 10L, 15L, 
    8L, 18L, 3L, 14L, 7L), .Label = c("BANK", "CENTRAL BANK", 
    "CIPLA", "CMC", "COGNIZANT", "DENA BANK", "DIVIS LABS", "DR. REDDYS", 
    "HCL TECH", "HEXAWARE", "IGATE", "INDIAN BANK", "INFOSYS", "LUPIN", 
    "MAHINDRA SATYAM", "PNB", "SBI", "SUN PHARMA", "TCS", "TECHMAHINDRA", 
    "UCO BANK", "UNION BANK", "VIJAYA BANK", "WIPRO"), class = "factor"), 
        Category = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
        2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), 
        .Label = c("BK", "IT", "PH"), class = "factor"), 
        Margin = c(34.5, 39.5, 39.9, 41.3, 42.3, 44.5, 44.5, 47.6, 49.8, 
        5.6, 5.9, 6.9, 12.6, 12.6, 15.8, 22.4, 22.9, 34.8, 34.8, 14.5, 
        19.2, 23.9, 23.9, 29), 
        Ranking = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L, 4L, 
        5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L)), 
        .Names = c("Company", "Category", "Margin", "Ranking"), 
        class = "data.frame", row.names = c(NA, -24L))
于 2013-10-17T16:23:59.070 回答
0

这是此问题的最终解决方案。

这是输入数据框

inDF <- structure(list(Company = structure(c(17L, 16L, 21L, 1L, 12L, 
    6L, 23L, 22L, 2L, 13L, 9L, 19L, 4L, 20L, 5L, 11L, 24L, 10L, 15L, 
    8L, 18L, 3L, 14L, 7L), .Label = c("BANK", "CENTRAL BANK", 
    "CIPLA", "CMC", "COGNIZANT", "DENA BANK", "DIVIS LABS", "DR. REDDYS", 
    "HCL TECH", "HEXAWARE", "IGATE", "INDIAN BANK", "INFOSYS", "LUPIN", 
    "MAHINDRA SATYAM", "PNB", "SBI", "SUN PHARMA", "TCS", "TECHMAHINDRA", 
    "UCO BANK", "UNION BANK", "VIJAYA BANK", "WIPRO"), class = "factor"), 
        Category = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
            2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), 
        .Label = c("BK", "IT", "PH"), class = "factor"), 
        Margin = c(34.5, 39.5, 39.9, 41.3, 42.3, 44.5, 44.5, 47.6, 49.8, 
        5.6, 5.9, 6.9, 12.6, 12.6, 15.8, 22.4, 22.9, 34.8, 34.8, 14.5, 
        19.2, 23.9, 23.9, 29), 
        Ranking = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 1L, 2L, 3L, 4L, 
        5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L)), 
        .Names = c("Company", "Category", "Margin", "Ranking"), 
        class = "data.frame", row.names = c(NA, -24L))

输入数据集如下所示

> mydf
           Company Category Margin Ranking
1              SBI       BK   34.5       1
2              PNB       BK   39.5       2
3         UCO BANK       BK   39.9       3
4             BANK       BK   41.3       4
5      INDIAN BANK       BK   42.3       5
6        DENA BANK       BK   44.5       6
7      VIJAYA BANK       BK   44.5       7
8       UNION BANK       BK   47.6       8
9     CENTRAL BANK       BK   49.8       9
10         INFOSYS       IT    5.6       1
11        HCL TECH       IT    5.9       2
12             TCS       IT    6.9       3
13             CMC       IT   12.6       4
14    TECHMAHINDRA       IT   12.6       5
15       COGNIZANT       IT   15.8       6
16           IGATE       IT   22.4       7
17           WIPRO       IT   22.9       8
18        HEXAWARE       IT   34.8       9
19 MAHINDRA SATYAM       IT   34.8      10
20      DR. REDDYS       PH   14.5       1
21      SUN PHARMA       PH   19.2       2
22           CIPLA       PH   23.9       3
23           LUPIN       PH   23.9       4
24      DIVIS LABS       PH   29.0       5

# 编写一个名为“rankCompany”的函数

> rankCompany <- function(inDF = mydf, catg, ranking) {
   if (ranking == "worst") {
      worst.ranks <- as.vector(table(inDF$Category))
      mgdf <- merge(inDF, data.frame(Category = catg, Ranking = worst.ranks), all.y = TRUE)
   } else if(is.numeric(ranking)) {
      mgdf <- merge(inDF, data.frame(Category = catg, Ranking = ranking), all.y = TRUE)
   }
   rownames(mgdf) <- catg
   return(mgdf)
 }

测试功能:

测试用例 #1

test1 <- c("BK", "IT", "PH")
rankCompany(catg = test1, ranking = 2)
  Category Ranking    Company Margin
BK       BK       2        PNB   39.5
IT       IT       2   HCL TECH    5.9
PH       PH       2 SUN PHARMA   19.2

测试用例#2

test2 <- c("BK", "IT", "PH")
rankCompany(catg = test2, ranking = 7)
   Category Ranking     Company Margin
BK       BK       7 VIJAYA BANK   44.5
IT       IT       7       IGATE   22.4
PH       PH       7        <NA>     NA

测试用例#3

test3 <- c("BK", "IT", "PH", "EG")
rankCompany(catg = test3, ranking = 10)

   Category Ranking         Company Margin
BK       BK      10            <NA>     NA
IT       IT      10 MAHINDRA SATYAM   34.8
PH       PH      10            <NA>     NA
EG       EG      10            <NA>     NA

测试用例#4

test4 <- c("BK", "IT", "PH")
rankCompany(catg = test4, ranking = "worst")

   Category Ranking         Company Margin
BK       BK       9    CENTRAL BANK   49.8
IT       IT      10 MAHINDRA SATYAM   34.8
PH       PH       5      DIVIS LABS   29.0
于 2013-10-18T03:17:41.903 回答