使用 data.table 计算所有数字列的汇总统计信息(例如平均值) [英] Calculate summary statistics (e.g. mean) on all numeric columns using data.table
问题描述
我有这样的 numeric
和非 numeric
列的数据:
I have data with both numeric
and non-numeric
columns like this:
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
列并使用 data.table
计算它们的 mean
?
How can I select only numeric
columns and calculate their mean
using 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>)
我也尝试了以下方法,但它不起作用:
I have also tried the following, but it does not work:
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 的建议,我尝试了以下但无法获得子集:
As suggested by @Arun, I tried following but cannot get a subset:
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 的一个子集,以便甚至不列出其他列.
As suggested by @David, I tried following but get NULL
values for non-numeric columns. I want to get a subset of mydt so that other columns are not even listed.
mydt[ , lapply(.SD, function(x) if(is.numeric(x)) mean(x))]
# vnum1 vint1 vfac1 vch1
# 1: -0.046491 4.5 NULL NULL
我缺少data.frame:
I am missing 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
好的.感谢大卫的评论,以下作品:
OK. Thanks to David's comment, following works:
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
,我找到了 this answer,我认为它很好地解释了如何使用它.
By searching on SO for .SDcols
, I landed up on this answer, which I think explains quite nicely how to use it.
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 并进行(深度)复制 - 不必要地使用了更多内存.
Doing mydt[, sapply(mydt, is.numeric), with = FALSE]
(note: the "modern" way to do that is mydt[ , .SD, .SDcols = is.numeric]
)is not that efficient because it subsets your data.table with those columns and that makes a (deep) copy - more memory used unnecessarily.
并且使用 colMeans
将 data.table 强制转换为 matrix
,这又不是那么内存效率.
And using colMeans
coerces the data.table into a matrix
, which again is not so memory efficient.
这篇关于使用 data.table 计算所有数字列的汇总统计信息(例如平均值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!