首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对多个数据文件的11层操作

对多个数据文件的11层操作
EN

Stack Overflow用户
提问于 2014-01-25 22:21:52
回答 2查看 1.9K关注 0票数 4

是否有一种简单的方法(即不必使用"for“循环)来执行以下操作:

我有几个数据帧。我想用一个plyr操作来总结它们。在这个例子中,我有两个数据框架,东方和西部,我想用国家支出和试验来总结这两个数据框架。

下面是数据帧示例:

代码语言:javascript
复制
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)
    )

以及这两种数据的合并列表:

代码语言:javascript
复制
combined <- c(west,east)

我想要做的是同时对这两个数据文件进行一次蹒跚学步的操作,并让输出成为一个列表(至少这看起来非常简单)。例如,如果我只是在一个dataframe上操作,它将是这样的:

代码语言:javascript
复制
country.df <- ddply(west, .(country), summarise,
    spend = sum(spend),
    trials = sum(trials)
)

但我想按比例做这件事。我尝试在llply参数中使用类似的语法,但这不起作用(我有一种感觉,我遗漏了一些明显得令人痛苦的东西):

代码语言:javascript
复制
countries.list <- llply(combined, .(country), summarise,
    spend = sum(spend),
    trials = sum(trials)
)

返回错误:“在乐趣中出错(X[1L],.):尝试应用非函数”

..。我可以想出一种方法来实现这一点,方法是编写一个函数,然后将它传递给一个应用参数。但是看起来,llply应该能够“开箱即用”,因为它是对工具所做的事情的一个相当简单的使用。

我在这里错过了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-25 22:53:46

我会这样做:

代码语言:javascript
复制
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
票数 5
EN

Stack Overflow用户

发布于 2014-01-26 00:23:01

下面是另一个使用dplyr的解决方案,它是数据帧plyr的一个高度优化版本。dplyr语法非常直观,IMHO比plyr更具可读性。如果说它读起来更像诗(至少在我看来是这样:),那就不算过分了。

代码语言:javascript
复制
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解决方案。请注意,对于大型数据帧,dplyrdata.table午餐时将吃plyr :)

代码语言:javascript
复制
library(data.table)
lapply(combined, function(dat){
  data.table(dat)[
  , list(trials = sum(trials), spend = sum(spend)),country][
  , status := ifelse(trials < 1000, "Good", "Bad")]
})

更新2:这是一个更深思熟虑的dplyr解决方案版本

代码语言:javascript
复制
lapply(combined, chain, group_by(country),
  summarise(trials = sum(trials), spend = sum(spend)),
  mutate(status = ifelse(trials < 1000, "Good", "Bad"))
)
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21357003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档