我有一个如下所示的数据框X:
A B C D E Identifier
1 2 3 4 5 a
2 3 2 2 1 b
4 5 4 5 3 a
2 3 4 5 6 a
0 0 1 2 3 a
1 2 1 1 1 b
(此处范围为6,因为记录观察的时间段为6。)
现在我想基于标识符计算A,B,C,D,E中的每一个的平均值。为此,我使用了 Process1
avgcalls <- function(calls){
totcalls <- sum(calls)
out <- totcalls/6
return(out)
}
avgcallsdf <- data.frame((aggregate(X[, 1:4], by = X[6], avgcalls)))
输出看起来像这样
Identifier A B C D
1 a 1.66667 1.6666667 2.0 2.5
2 b 0.50000 0.8333333 0.5 0.5
或者我做了(请建议一个更好的方法来执行此操作)
Process2
samp1<-D[which(D$Identifier=='a')] #creating one dataframe with identifier as 'a'
samp2<-D[which(D$Identifier=='b')]#creating another dataframe with'b'as identifier
#calculating means
mean1<-sum(sampl$A, na.rm=TRUE)/6
mean2<-sum(sampl$B, na.rm=TRUE)/6
mean3<-sum(sampl$C, na.rm=TRUE)/6
mean4<-sum(sampl$D, na.rm=TRUE)/6
mean5<-sum(samp1$E, na.rm=TRUE)/6
finaldf<-data.frame(mean1,mean2,mean3,mean4,mean5)
我同样用 samp2 进行上述操作 两个结果都是相同的。
我的实际数据有1008列和大约80,000行,结果会有所不同 过程1和过程2是否存在NA?
我看了这个Getting different results using aggregate() and sum() functions in R,但这不是很有帮助
答案 0 :(得分:3)
我们也可以使用data.table
library(data.table)
setDT(df1)[, lapply(.SD, mean), Identifier]
# Identifier A B C D E
#1: a 1.75 2.5 3.0 4.0 4.25
#2: b 1.50 2.5 1.5 1.5 1.00
如果我们需要sum
除以n=6
setDT(df1)[, lapply(.SD, function(x) sum(x, na.rm=TRUE)/6), Identifier]
# Identifier A B C D E
#1: a 1.166667 1.6666667 2.0 2.666667 2.8333333
#2: b 0.500000 0.8333333 0.5 0.500000 0.3333333
答案 1 :(得分:2)
这是在dplyr
中分两行解决此问题的好方法。
library(dplyr)
df <- data.frame(A=c(1, 2, 4, 2, 0, 1), B=c(2, 3, 5, 3 ,0, 2), C=c(3, 2, 4, 4, 1, 1), D=c(4, 2, 5, 5, 2, 1), E=c(5, 1, 3, 6, 3, 1), Identifier=c('a', 'b', 'a', 'a', 'a', 'b'))
df %>%
group_by(Identifier) %>%
summarise(A = mean(A), B = mean(B), C = mean(C), D = mean(D), E = mean(E))
应该给你
Identifier A B C D E
a 1.75 2.5 3.0 4.0 4.25
b 1.50 2.5 1.5 1.5 1.00
(注意我的数字与你的数字不同 - 我希望这是因为你在整个数据集上运行了这个,而不仅仅是像我一样运行的。)
修改强>
你也可以做@TheTime说的,并保存一些墨水:
summarise_each(funs(mean))
答案 2 :(得分:2)
另一种解决方案使用&#34;聚合&#34;,&#34; a&#34;作为数据框架,假设&#34;标识符&#34;在最后一栏:
Identifier A B C D E
1 a 1.75 2.5 3.0 4.0 4.25
2 b 1.50 2.5 1.5 1.5 1.00
或更紧凑,使用@thelatemail指出的公式界面:
from pprint import pprint
from itertools import chain
pprint([(key, type(val).__name__, id(val))
for key, val in chain.from_iterable(x.items() for x in products.values())])
给出:
[('Cheese', 'dict', 64885352L),
('MPC70', 'dict', 64887800L),
('MPI:', 'dict', 64887800L),
('MPC85', 'dict', 64887800L),
('Whey Powder', 'dict', 65061480L),
('Casein', 'dict', 65061752L),
('Lactose', 'dict', 65062024L),
('NFDM', 'dict', 65062296L),
('Caseinate', 'dict', 65062568L),
('Butter', 'dict', 65063112L),
('WPC80', 'dict', 65062840L),
('IWPC80', 'dict', 65062840L)]
答案 3 :(得分:2)
您可以使用公式界面更简单地使用aggregate
编辑你的功能还可以让你更轻松地为你的分母传递n=
:
avgcalls <- function(x,n) sum(x,na.rm=TRUE)/n
aggregate(. ~ Identifier, data=dat, FUN=avgcalls, n=6, na.action=na.pass)
# Identifier A B C D E
#1 a 1.166667 1.6666667 2.0 2.666667 2.8333333
#2 b 0.500000 0.8333333 0.5 0.500000 0.3333333