我正在尝试将不同的函数应用于不同的列以用于分组数据,但我不确定为什么其中一个函数不起作用。我在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
的答案
我很感激任何想法。
答案 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已激活。