我一直在玩一些数据,以获得一个变量中两个级别之间的比率,并考虑另外两个变量。我一直在使用函数 aggregate(),这对计算均值和总和非常有用。但是,当我想计算一些比率(分数)时,我就陷入了困境。 在这里,您可以找到与我的数据非常相似的数据框:
w<-c("A","B","C","D","E","F","A","B","C","D","E","F")
x<-c(1,1,1,1,1,1,2,2,2,2,2,2)
y<-c(3,4,5,6,8,10,3,4,5,7,9,10)
z<-runif(12)
df<-data.frame(w,x,y,z)
df
w x y z
1 A 1 3 0.93767621
2 B 1 4 0.09169992
3 C 1 5 0.49012926
4 D 1 6 0.90886690
5 E 1 8 0.37058120
6 F 1 10 0.83558267
7 A 2 3 0.42670001
8 B 2 4 0.05656252
9 C 2 5 0.70694423
10 D 2 7 0.13634309
11 E 2 9 0.92065671
12 F 2 10 0.56276176
我想要的是从x的两个级别获得z的比率并考虑变量w和y。因此,来自变量“y”的级别“3”中变量“w”的级别“A”应为:
df$z[1]/df$z[7]
聚合函数应该是这样的:
final<-aggregate(z~y:w, data=df)
然而,我知道我错过了一些东西,因为在变量y中有一些类没有出现在两类w中(例如7,8和9)。
欢迎任何帮助!
答案 0 :(得分:1)
我们可以使用data.table
。我们将'data.frame'转换为'data.table'(setDT(df)
),按'w'分组,'y',if
nrow(.N
)为2,我们将第一个值除以第二个值,或else
返回“z”。将输出(:=
)分配给新列'z1'。
library(data.table)
setDT(df)[,z1 :=if(.N==2) z[1]/z[2] else z , by = .(w,y)]
df
# w x y z z1
# 1: A 1 3 0.93767621 2.1975069
# 2: B 1 4 0.09169992 1.6212135
# 3: C 1 5 0.49012926 0.6933068
# 4: D 1 6 0.90886690 0.9088669
# 5: E 1 8 0.37058120 0.3705812
# 6: F 1 10 0.83558267 1.4847894
# 7: A 2 3 0.42670001 2.1975069
# 8: B 2 4 0.05656252 1.6212135
# 9: C 2 5 0.70694423 0.6933068
#10: D 2 7 0.13634309 0.1363431
#11: E 2 9 0.92065671 0.9206567
#12: F 2 10 0.56276176 1.4847894
如果我们只想要summary
输出,则无需使用:=
setDT(df)[, list(z=if(.N==2) z[1]/z[2] else z) , by = .(w,y)]
或使用aggregate
aggregate(z~w+y, df, FUN=function(x)
if(length(x)==2) x[1]/x[2] else x)