我有这样的数据numeric
和非numeric
列:
mydt
vnum1 vint1 vfac1 vch1
1: -0.30159484 8 3 E
2: -0.09833430 8 1 D
3: -2.15963282 1 3 D
4: 0.03904374 5 2 B
5: 1.54928970 4 1 C
6: -0.73873654 5 1 A
7: -0.68594479 9 2 B
8: 1.35765612 1 2 E
9: 1.46958351 2 1 B
10: -0.89623979 2 4 E
如何仅选择numeric
列并计算其mean
使用量data.table
?
我已经试过了:
mydt[ , lapply(.SD, mean), ]
# vnum1 vint1 vfac1 vch1
# 1: -0.046491 4.5 NA NA
# Warning messages:
# 1: In mean.default(X[[3L]], ...) :
# argument is not numeric or logical: returning NA
# 2: In mean.default(X[[4L]], ...) :
# argument is not numeric or logical: returning NA
dput(mydt)
structure(list(vnum1 = c(-0.301594844692861, -0.0983343040483769,
-2.15963282153076, 0.03904374068617, 1.54928969700272, -0.738736535236348,
-0.685944791146016, 1.35765612481877, 1.46958350568506, -0.896239790653183
), vint1 = c(8L, 8L, 1L, 5L, 4L, 5L, 9L, 1L, 2L, 2L), vfac1 = structure(c(3L,
1L, 3L, 2L, 1L, 1L, 2L, 2L, 1L, 4L), .Label = c("1", "2", "3",
"4"), class = "factor"), vch1 = structure(c(5L, 4L, 4L, 2L, 3L,
1L, 2L, 5L, 2L, 5L), .Label = c("A", "B", "C", "D", "E"), class = "factor")), .Names = c("vnum1",
"vint1", "vfac1", "vch1"), class = c("data.table", "data.frame"
), row.names = c(NA, -10L), .internal.selfref = <pointer: 0x991c070>)
我也尝试了以下方法,但是不起作用:
mydt[ , lapply(.SD, is.numeric),]
# vnum1 vint1 vfac1 vch1
# 1: TRUE TRUE FALSE FALSE
mydt[,mydt[,lapply(.SD, is.numeric),]]
# vnum1 vint1 vfac1 vch1
# 1: TRUE TRUE FALSE FALSE
mydt[ , mydt[ , lapply(.SD, is.numeric) , ], with = F]
# Error in Math.data.frame(j) :
# non-numeric variable in data frame: vnum1vint1vfac1vch1
mydt[ , c(mydt[ , lapply(.SD, is.numeric)), ], with = F]
# Error: unexpected ')' in "mydt[,c(mydt[,lapply(.SD, is.numeric))"
正如@Arun所建议的那样,我尝试了以下操作,但无法获得子集:
xx <- mydt[ , lapply(.SD, is.numeric), ]
xx
# vnum1 vint1 vfac1 vch1
# 1: TRUE TRUE FALSE FALSE
mydt[ , lapply(.SD, mean), .SDcols = xx]
# Error in `[.data.table`(mydt, , lapply(.SD, mean), .SDcols = xx) :
# .SDcols should be column numbers or names
正如@David所建议的那样,我尝试了以下操作,但获取NULL
了非数字列的值。我想获取mydt的子集,以便甚至不列出其他列。
mydt[ , lapply(.SD, function(x) if(is.numeric(x)) mean(x))]
# vnum1 vint1 vfac1 vch1
# 1: -0.046491 4.5 NULL NULL
我缺少data.frame:
sapply(mydf, is.numeric)
# vnum1 vint1 vfac1 vch1
# TRUE TRUE FALSE FALSE
mydf[sapply(mydf, is.numeric)]
# vnum1 vint1
#1 -0.30159484 8
#2 -0.09833430 8
#3 -2.15963282 1
#4 0.03904374 5
#5 1.54928970 4
#6 -0.73873654 5
#7 -0.68594479 9
#8 1.35765612 1
#9 1.46958351 2
#10 -0.89623979 2
sapply(mydf[sapply(mydf, is.numeric)], mean)
# vnum1 vint1
#-0.046491 4.500000
好的。感谢David的评论,以下作品:
mydt[, sapply(mydt, is.numeric), with = FALSE][,sapply(.SD, mean),]
# vnum1 vint1
# -0.046491 4.500000
mydt[, sapply(mydt, is.numeric), with = FALSE]
# vnum1 vint1
# 1: -0.30159484 8
# 2: -0.09833430 8
# 3: -2.15963282 1
# 4: 0.03904374 5
# ...
通过在SO上搜索.SDcols
,我找到了这个答案,我认为它很好地解释了如何使用它。
cols = sapply(mydt, is.numeric)
cols = names(cols)[cols]
mydt[, lapply(.SD, mean), .SDcols = cols]
# vnum1 vint1
# 1: -0.046491 4.5
这样做mydt[, sapply(mydt, is.numeric), with = FALSE]
(注意:做到这一点的“现代”方法mydt[ , .SD, .SDcols = is.numeric]
)效率不高,因为它使用这些列将data.table子集化,并产生了(深层)副本-不必要地使用了更多内存。
并使用colMeans
将data.table强制转换为matrix
,这又不是那么高效的内存。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句