如何为data.frame中的国家/地区创建基于年份的个人数据方式?

时间:2017-04-17 10:31:32

标签: r

我正在处理一个有大量数据帧,包含341k观测值和1.4k变量。观察结果包含多年来各国的个人数据。我现在想要为每个国家创建基于年份的个人数据:

set.seed(42)
ctry <- c(rep("AU", 6),rep("BY", 6),rep("CH", 6),rep("DE", 6))
year <- c(rep(2001,2),rep(2002,2),rep(2003,2),rep(2001,2),rep(2002,2),rep(2003,2),
      rep(2001,2),rep(2002,2),rep(2003,2),rep(2001,2),rep(2002,2),rep(2003,2))
a <- rnorm(24,1,.1)
b <- rnorm(24,2,.2)
c <- rnorm(24,3,.3)
(df <- data.frame(ctry,year,a,b,c))

我发现this符合我的问题, Peter Lustig 给了一个很棒的answer。对于我自己,我找到了ave()函数的解决方案,但它对1.4k变量非常不方便:

df1 <- df
df1$mean.a <- ave(df[[3]], df[[2]], df[[1]])
df1$mean.b <- ave(df[[4]], df[[2]], df[[1]])
df1$mean.c <- ave(df[[5]], df[[2]], df[[1]])
(df2 <- unique(df1[,c(1,2,(ncol(df1)-2):ncol(df1))]))

akrun的 function看起来很有希望,但我无法适合我。也许有更简洁的解决方案?感谢。

1 个答案:

答案 0 :(得分:0)

根据OP的ave输出,似乎我们按相同的列进行分组并获得其他列的mean。因此,我们需要ave小组,而不是summarise。这可以使用dplyr

完成
library(dplyr)
df %>% 
   group_by(ctry, year) %>% 
   summarise_at(.vars = names(df)[3:5], funs(Mean = mean))

或者如果我们需要获得除分组变量之外的所有变量的mean,如@StevenBeaupre建议的那样,我们可以使用summarise_all

df %>% 
   group_by(ctry, year) %>% 
   summarise_all(mean)
#    ctry  year         a        b        c
#   <fctr> <dbl>     <dbl>    <dbl>    <dbl>
#1      AU  2001 1.0403130 2.146472 3.033630
#2      AU  2002 1.0497996 1.797957 2.930713
#3      AU  2003 1.0149072 1.982010 3.332794
#4      BY  2001 1.0708431 2.116029 3.054947
#5      BY  2002 1.0977855 2.042618 3.115368
#6      BY  2003 1.1795758 1.878795 2.593769
#7      CH  2001 0.9166175 1.836463 2.972699
#8      CH  2002 1.0251315 1.762191 3.297234
#9      CH  2003 0.8529646 1.984494 3.086288
#10     DE  2001 0.9439823 2.003146 3.206153
#11     DE  2002 0.8956026 1.906454 3.246241
#12     DE  2003 1.0521379 2.063271 2.830004

为方便起见,我们还可以将此包装在一个函数中,该函数使用quosures的开发版本中的dplyr

fMean <- function(dat, grp1, grp2, otherVars){
    #enquo does similar functionality as substitute from base R
    grp1 <- enquo(grp1) 
    grp2 <- enquo(grp2)

    dat %>%
       #evaluate the quosure by unquote (UQ or !!)
       group_by(!!grp1, !!grp2) %>%
       summarise_at(.vars = otherVars, funs(Mean = mean))


} 

fMean(df, ctry, year, names(df)[3:5])
#     ctry  year    a_Mean   b_Mean   c_Mean
#   <fctr> <dbl>     <dbl>    <dbl>    <dbl>
#1      AU  2001 1.0403130 2.146472 3.033630
#2      AU  2002 1.0497996 1.797957 2.930713
#3      AU  2003 1.0149072 1.982010 3.332794
#4      BY  2001 1.0708431 2.116029 3.054947
#5      BY  2002 1.0977855 2.042618 3.115368
#6      BY  2003 1.1795758 1.878795 2.593769
#7      CH  2001 0.9166175 1.836463 2.972699
#8      CH  2002 1.0251315 1.762191 3.297234
#9      CH  2003 0.8529646 1.984494 3.086288
#10     DE  2001 0.9439823 2.003146 3.206153
#11     DE  2002 0.8956026 1.906454 3.246241
#12     DE  2003 1.0521379 2.063271 2.830004

dplyr外,我们还可以使用data.table

library(data.table)
setDT(df)[, lapply(.SD, mean), .(ctry, year)]

此处,setDT会转换&#39; data.frame&#39;到data.table,按&#39; ctry&#39;年份&#39;分组,我们遍历Data.table的Subset列并获取mean。如果我们只需要获取特定列的mean,请在.SDcols

中指定
setDT(df)[, lapply(.SD, mean), .(ctry, year), .SDcols = a:c]

base Raggregate

aggregate(.~ctry + year, df, mean)