R 基于分组对数据帧进行分组并对多列中的行进行平均,忽略零
我的数据框R 基于分组对数据帧进行分组并对多列中的行进行平均,忽略零,r,dplyr,R,Dplyr,我的数据框数据如下所示: Week Group Cost Revenue Wk1 A 104 148 Wk1 A 0 159 Wk1 A 92 151 Wk1 A 113 144 Wk1 B 331 500 WK1 B 325 524 Wk1 B 363 488 Wk1 B 0 497 Wk2 A
数据如下所示:
Week Group Cost Revenue
Wk1 A 104 148
Wk1 A 0 159
Wk1 A 92 151
Wk1 A 113 144
Wk1 B 331 500
WK1 B 325 524
Wk1 B 363 488
Wk1 B 0 497
Wk2 A 132 0
.
.
.
以下是我从无序csv文件中获取的R代码:
library(dplyr)
d <- read.csv(...)
data <- tbl_df(d)
data <- arrange(data, Group, Week)
问题:
我如何平均我的专栏按他们的组和他们的星期分组,这样我就可以得到上面想要的结果?我想使用dplyr
包来完成此操作
问题:
我的一些行有零。我不想求零的平均值(所以不是(104+0+92+113)/4
,而是忽略它们,所以(104+92+113)/3
)。我也不能简单地filter()
将带有零的行过滤掉,因为通常情况下,我的成本或收入列中只有一列同时包含零而不是两列
我知道我可以使用summary()
使用mean()
进行平均,但不确定如何按照我需要的方式对平均值进行分组,并在计算中忽略零
谢谢 您可以使用data.table
包。它确实快了100倍,更直观
您可以使用fread
功能将csv文件读取到data.tables。但这里只是一个例子
DT = data.table(Week = c("wk1","wk2"), Group = c("A","B","C","D"), Cost = sample(1:49,30,replace=F), Revenue = sample(1:49,10,replace=F))
# Week Group Cost Revenue
# 1: wk1 A 33 37
# 2: wk2 B 17 28
# 3: wk1 C 13 6
# 4: wk2 D 39 25
# 5: wk1 A 15 3
# 6: wk2 B 34 8
# 7: wk1 C 2 12
# 8: wk2 D 9 11
# 9: wk1 A 48 18
#10: wk2 B 25 29
#11: wk1 C 46 37
#12: wk2 D 11 28
#13: wk1 A 22 6
#14: wk2 B 6 25
#15: wk1 C 26 3
#16: wk2 D 40 8
#17: wk1 A 27 12
#18: wk2 B 23 11
#19: wk1 C 43 18
#20: wk2 D 24 29
#21: wk1 A 21 37
#22: wk2 B 29 28
#23: wk1 C 31 6
#24: wk2 D 8 25
#25: wk1 A 36 3
#26: wk2 B 5 8
#27: wk1 C 1 12
#28: wk2 D 19 11
#29: wk1 A 4 18
#30: wk2 B 44 29
# Week Group Cost Revenue
在下一行中,您应该定义用于分组的列;这里我使用c(“周”、“组”)
有关更多信息,请参阅数据表软件包手册:
为了忽略mean
函数中的零,可以将其替换为nzmean
。请参阅本帖:
没有任何附加包的解决方案:
# Define a non-zero means function
nzmean <- function(x) {
zvals <- x==0
if (all(zvals)) 0 else mean(x[!zvals])
}
我想我应该添加一个dplyr答案
首先,您可以在摘要
中执行此操作,使用提取功能([
)分别从成本
和收入
中删除任何0值
就打字效率而言,summary\u each
是另一个有用的选项,在这种情况下,您需要在多个列上使用相同的函数。您可以利用
编码在取平均值时从每个数值变量中删除任何0值
dat %>% group_by(Week, Group) %>%
summarise_each(funs(mean(.[. > 0])))
您想使用dplyr
package有什么特别的原因吗?它直观、实用(在编程范例的意义上),我正在努力更好地学习。虽然我对其他技术持开放态度。我喜欢这种方法,但如果成本或收入列中有一些0呢?我需要忽略平均值函数中的0。你可以用定义的函数替换mean
。请看这篇文章:用nzmean
替换mean
,其中nz@MahdiJadaliha是一个很好的答案,但是你在没有证据的情况下做了两个陈述:data.table“确实比原来快了100倍,而且更直观”。如果你想让我们相信它更快,至少你可以链接到另一个帖子作为证据。说到直觉,好吧,我来判断一下:-)@BarkleyBG,datatable仍然是最快的(在大多数情况下,100倍可能是夸张的)。下面是性能基准的链接:
nzmean <- function(x) {
zvals <- x==0
if (all(zvals)) 0 else mean(x[!zvals])
}
DT[,list(Avg_Cost = nzmean(Cost),Avg_Revenue = nzmean(Revenue)),by = c("Week", "Group")]
# Define a non-zero means function
nzmean <- function(x) {
zvals <- x==0
if (all(zvals)) 0 else mean(x[!zvals])
}
tapply(df$Cost,list(df$Week,df$Group),nzmean )
require(dplyr)
dat %>% group_by(Week, Group) %>%
summarise(Cost = mean(Cost[Cost > 0]), Revenue = mean(Revenue[Revenue > 0]))
dat %>% group_by(Week, Group) %>%
summarise_each(funs(mean(.[. > 0])))