分组后,将不同的功能应用于不同的列

时间:2017-05-07 01:20:54

标签: r data.table dplyr

我正在尝试将不同的函数应用于不同的列以用于分组数据,但我不确定为什么其中一个函数不起作用。我在R - Group data but apply different functions to different columns这个帖子上研究了这个主题,但我相信他们在这个例子中没有使用lapply。在我的示例中,我想连接所有ID并将sum应用于所有数字列。

这是我的输入数据:

dput(Input)
structure(list(ID = c(1, 2, 3, 4, 5, 6), Name = c("Boston", "Boston", 
"Boston", "Boston", "Seattle", "Washington"), Total_Groceries = c(35, 
70, 95, 120, 10, 20), Apple = c(5, 10, 15, 20, 2, 10), Banana = c(10, 
20, 30, 40, 5, 8), Pineapple = c(20, 40, 50, 60, 3, 2)), .Names = c("ID", 
"Name", "Total_Groceries", "Apple", "Banana", "Pineapple"), row.names = c(NA, 
6L), class = "data.frame")

这是我的代码:

 Input<-data.table::as.data.table(Input)

  Input[,as.list(ID=paste0(ID,collapse=";"),unlist(lapply(.SD, sum, na.rm=TRUE))),by=.(Name),.SDcols=c("Total_Groceries","Apple","Banana","Pineapple")]

在代码上运行,您会看到我没有为ID

获取连接字符串

这是预期的输出:

dput(Output)
structure(list(ID = c("1;2;3;4", "5", "6"), Name = c("Boston", 
"Seattle", "Washington"), Total_Groceries = c(320, 10, 20), Apple = c(50, 
2, 10), Banana = c(100, 5, 8), Pineapple = c(170, 3, 2)), .Names = c("ID", 
"Name", "Total_Groceries", "Apple", "Banana", "Pineapple"), row.names = c(NA, 
3L), class = "data.frame")

作为奖励(对于我的学习,如果您可以根据dplyr发布答案,那将非常有用。由于原始数据的庞大规模,我主要寻找基于data.table的答案

我很感激任何想法。

2 个答案:

答案 0 :(得分:1)

这不是最优雅的解决方案,但这是使用dplyr实现此目的的一种方法。


library(tibble)
library(dplyr)

input <- tibble::tribble(
  ~ID,         ~Name, ~Total_Groceries, ~Apple, ~Banana, ~Pineapple,
  1L,      "Boston",              35L,     5L,     10L,        20L,
  2L,      "Boston",              70L,    10L,     20L,        40L,
  3L,      "Boston",              95L,    15L,     30L,        50L,
  4L,      "Boston",             120L,    20L,     40L,        60L,
  5L,     "Seattle",              10L,     2L,      5L,         3L,
  6L,  "Washington",              20L,    10L,      8L,         2L
)

input %>% 
  group_by(Name) %>% 
  mutate_at(vars(ID), funs(paste(., collapse = ";"))) %>% 
  group_by(Name, ID) %>% 
  summarise_if(is.numeric, sum, na.rm = TRUE)
#> Source: local data frame [3 x 6]
#> Groups: Name [?]
#> 
#>         Name      ID Total_Groceries Apple Banana Pineapple
#>        <chr>   <chr>           <int> <int>  <int>     <int>
#> 1     Boston 1;2;3;4             320    50    100       170
#> 2    Seattle       5              10     2      5         3
#> 3 Washington       6              20    10      8         2

答案 1 :(得分:1)

另一个data.table方法跟随弗兰克建议拆分操作以允许sum进行Gforce优化

df[, paste(ID, collapse=";"), by=Name
   ][df[, lapply(.SD, sum), .SDcols=Total_Groceries:Pineapple, by=Name],
   on="Name"]
         Name      V1 Total_Groceries Apple Banana Pineapple
1:     Boston 1;2;3;4             320    50    100       170
2:    Seattle       5              10     2      5         3
3: Washington       6              20    10      8         2

这个想法是首先折叠ID,然后合并data.table,按名称计算剩余列的总和。在.SDcols参数中明确列出了要求和的列的选择。请注意,如果在第二个链的i参数中添加verbose = TRUE,您将在此计算中看到GForce已激活。