在R中,基于单个列的意思是其他所有列的平均值。

3

我有一个大型数据框,其中包含超过40,000列。我遇到了类似于在R中按不同列值求和的问题。

shop <- data.frame( 
  'shop_id' = c('Shop A', 'Shop A', 'Shop A', 'Shop B', 'Shop C', 'Shop C'), 
  'Assets' = c(2, 15, 7, 5, 8, 3),
  'Liabilities' = c(5, 3, 8, 9, 12, 8),
  'sale' = c(12, 5, 9, 15, 10, 18), 
  'profit' = c(3, 1, 3, 6, 5, 9))

我有一个名为shop_id的列,它被重复多次。我有与该shop_id相关联的其他值,例如资产、负债、利润、损失等。现在我想要对所有具有相同shop_id的变量进行平均,即我想要唯一的shop_ids并且想要平均具有相同shop_id的所有列。由于有数千个变量(列),分别处理每个变量非常繁琐。

我的答案应该是:

 shop_id  Assets  Liabilities     sale    profit    
 Shop A   8.0     5.333333    8.666667  2.333333
 Shop B   5.0     9.000000   15.000000  6.000000
 Shop C   5.5    10.000000   14.000000  7.000000

目前我正在使用以下嵌套for循环: 尽管R是多才多艺的,但我相信应该有一种更快的方法来完成这个任务。

idx <- split(1:nrow(shop), shop$shop_id)

newdata <- data.frame()

for( i in 1:length(idx)){
    newdata[i,1]<-c(names(idx)[i] )
    for (j in 2:ncol(shop)){
        newdata[i,j]<-mean(shop[unlist(idx[i]),j])
    }
}
4个回答

3
尝试使用 data.table
library(data.table)
setDT(shop)[, lapply(.SD, mean), shop_id]
#  shop_id Assets Liabilities      sale   profit
#1:  Shop A    8.0    5.333333  8.666667 2.333333
#2:  Shop B    5.0    9.000000 15.000000 6.000000
#3:  Shop C    5.5   10.000000 14.000000 7.000000

或者

library(dplyr)
shop %>% 
    group_by(shop_id)%>%
    summarise_each(funs(mean))
# shop_id Assets Liabilities      sale   profit
#1  Shop A    8.0    5.333333  8.666667 2.333333
#2  Shop B    5.0    9.000000 15.000000 6.000000
#3  Shop C    5.5   10.000000 14.000000 7.000000

或者

aggregate(.~shop_id, shop, FUN=mean)
#   shop_id Assets Liabilities      sale   profit
#1  Shop A    8.0    5.333333  8.666667 2.333333
#2  Shop B    5.0    9.000000 15.000000 6.000000
#3  Shop C    5.5   10.000000 14.000000 7.000000

对于 40,000 列的数据,我会使用 data.table 或者可能是 dplyr


2

尝试使用dplyr

library("dplyr")
shop %>% group_by(shop_id) %>% summarise_each(funs(mean))

#   shop_id Assets Liabilities      sale   profit
# 1  Shop A    8.0    5.333333  8.666667 2.333333
# 2  Shop B    5.0    9.000000 15.000000 6.000000
# 3  Shop C    5.5   10.000000 14.000000 7.000000

2

rowsum 可以在这里发挥作用:

rowsum(shop[-1], shop[[1]]) / table(shop[[1]])
#       Assets Liabilities      sale   profit
#Shop A    8.0    5.333333  8.666667 2.333333
#Shop B    5.0    9.000000 15.000000 6.000000
#Shop C    5.5   10.000000 14.000000 7.000000

那是一些创新的想法。 - akrun

1
使用plyr包中的ddply函数:

ddply

> require("plyr")
> ddply(shop, ~shop_id, summarise, Assets=mean(Assets),
        Liabilities=mean(Liabilities), sale=mean(sale), profit=mean(profit))

  shop_id Assets Liabilities      sale   profit
1  Shop A    8.0    5.333333  8.666667 2.333333
2  Shop B    5.0    9.000000 15.000000 6.000000
3  Shop C    5.5   10.000000 14.000000 7.000000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接