7

这就是我想要做的。我的数据框有一个因子变量“国家”,我想根据国家/地区拆分数据框。然后,我想对每个国家的数据框的每个变量取列均值。

这里的数据:https ://github.com/pourque/country-data

到目前为止,我已经这样做了...

myList <- split(df1, df1$country)
for(i in 1:length(myList)) {
aggregate <- mapply(myList[[i]][,-c(38:39)], colMeans)
}

(我不包括第 38 列和第 39 列,因为它们是因素。)

我读过这个(函数超过一个列表),这让我认为 mapply 是这里的答案......但我收到了这个错误:

Error in match.fun(FUN) : 
'myList[[i]][, -c(38:39)]' is not a function, character or symbol 

也许我格式不正确?

4

4 回答 4

7

在基础 R 中使用它很简单,aggregate无需split事先将 data.frame 放入列表中。这是一个使用内置 iris 数据的示例,您可以在其中mean按组计算除第一列和第二列中的变量之外的所有变量的Species

data(iris)
aggregate(. ~ Species, iris[-(1:2)], mean)
#     Species Petal.Length Petal.Width
#1     setosa        1.462       0.246
#2 versicolor        4.260       1.326
#3  virginica        5.552       2.026

内部用于指定您要使用 data.frame 的所有剩余列,除了分组变量(在本例中为 Species).aggregate并且因为您指定iris[-(1:2)]为输入数据,所以也不使用第一列和第二列。


对于您的数据,它应该类似于:

aggregate(. ~ country, df1[-c(38:39)], mean)
于 2015-05-04T17:19:45.420 回答
6
library(dplyr)

df1 %>%
    group_by(country) %>%
    select(-age, -gender) %>%
    summarise_each(funs(mean))
于 2015-05-04T17:02:55.467 回答
4

如果您坚持将所有内容都保留在列表中:

#split and make list of df
myList <- split(df, df$country)

#aggregate without age and gender
my_aggregate <- function(df_inlist) {
  df_inlist <- aggregate(.~country, df_inlist[ , -c(38, 39)], mean)
}

#Apply aggregate function on all data frames in the list
out <- lapply(myList, function (x) {
  my_aggregate(x)
})

outlist每个国家的 data.frames 和 colmeans 变量。如何将它们放在一个 data.frame 中:

composite_df <- do.call(rbind, out)
于 2015-05-04T17:13:16.147 回答
3

一个 data.table 答案:

library(data.table)

setDT(df1)[, lapply(.SD, mean), by = country, .SDcols = -c('age', 'gender')]

由于用户 Arun,现在在 .SDcols 中取消选择的语法更整洁

要解释这里发生的事情:

  • setDT(df1)使 data.frame 成为 data.table
  • lapply(.SD, mean)对于数据子集中的每一列,取mean
  • by = county按组分组执行此操作country
  • .SDcols = -c('age', 'gender')数据子集中的省略agegender
于 2015-05-04T17:10:10.123 回答