是否有一种简单的方法(即,无需使用“for”循环)来执行以下操作:
我有几个数据框。我想使用 plyr 操作来总结它们。在这个例子中,我有两个数据框,东部和西部,我想用国家的花费和试验来总结它们。
以下是示例数据框:
west <- data.frame(
spend = sample(50:100,50,replace=T),
trials = sample(100:200,50,replace=T),
country = sample(c("usa","canada","uk"),50,replace = T)
)
east <- data.frame(
spend = sample(50:100,50,replace=T),
trials = sample(100:200,50,replace=T),
country = sample(c("china","japan","skorea"),50,replace = T)
)
以及两个数据帧的组合列表:
combined <- c(west,east)
我想要做的是同时对这两个数据帧进行ddply类型操作,并将输出作为一个列表(至少看起来最简单)。例如,如果我只是在一个数据帧上运行,那就像是:
country.df <- ddply(west, .(country), summarise,
spend = sum(spend),
trials = sum(trials)
)
但我想大规模地这样做。我尝试在llply参数中使用类似的语法,但这不起作用(我有一种感觉,我错过了一些非常明显的东西):
countries.list <- llply(combined, .(country), summarise,
spend = sum(spend),
trials = sum(trials)
)
返回错误:“FUN中的错误(X [[1L]],...):尝试应用非功能”
...我可以想办法通过编写一个函数,然后将其传递给apply参数来实现。但似乎 llply 应该能够处理这种“开箱即用”,因为它可以相当直接地使用该工具。
我在这里缺少什么?
答案 0 :(得分:7)
这是另一个使用dplyr
的解决方案,plyr
是数据框的dplyr
的高度优化版本。 plyr
语法非常直观,恕我直言比combine = list(west = west, east = east)
library(dplyr)
lapply(combined, function(dat){
dat %.%
group_by(country) %.%
summarise(
trials = sum(trials),
spend = sum(spend)
) %.%
mutate(
status = ifelse(trials < 1000, "Good", "Bad")
)
})
更具可读性。如果说它更像是诗歌(至少在我眼里:),那就不夸张了。)
data.table
EDIT。为了完整起见,这是dplyr
解决方案。请注意,对于大型数据框,data.table
和plyr
将在午餐时吃library(data.table)
lapply(combined, function(dat){
data.table(dat)[
, list(trials = sum(trials), spend = sum(spend)),country][
, status := ifelse(trials < 1000, "Good", "Bad")]
})
:)
dplyr
更新2:这是lapply(combined, chain, group_by(country),
summarise(trials = sum(trials), spend = sum(spend)),
mutate(status = ifelse(trials < 1000, "Good", "Bad"))
)
解决方案
{{1}}
答案 1 :(得分:5)
我会这样做:
combined <- list(east, west)
lapply(combined, ddply, .(country), summarise, spend = sum(spend),
trials = sum(trials))
# [[1]]
# country spend trials
# 1 china 1572 2976
# 2 japan 1075 1989
# 3 skorea 1262 2526
#
# [[2]]
# country spend trials
# 1 canada 1459 3117
# 2 uk 910 1967
# 3 usa 1248 2660