在data.table中使用.SD和.SDcols与mean函数

8
我正在编写一个非常简单的函数来汇总数据表列。我一次将一列传递给函数,然后进行一些诊断以确定汇总选项,然后进行汇总。我在data.table中进行此操作,以允许处理非常大的数据集。
因此,我使用.SDcols来传递要汇总的列,并在data.table表达式的j部分上使用.SD的函数。因为我一次只传递一列,所以我没有使用lapply。我发现有些函数可以正常工作,而有些函数不能正常工作。以下是我正在使用的测试数据集和我看到的结果:
dt <- data.table(
  a=1:10, 
  b=as.factor(letters[1:10]), 
  c=c(TRUE, FALSE), 
  d=runif(10, 0.5, 100), 
  e=c(0,1), 
  f=as.integer(c(0,1)), 
  g=as.numeric(1:10), 
  h=c("cat1", "cat2", "cat3", "cat4", "cat5"))

mean(dt$a)
[1] 5.5

dt[, mean(.SD), .SDcols = "a"]

[1] NA
Warning message:
In mean.default(.SD) : argument is not numeric or logical: returning NA

dt[, sum(.SD), .SDcols = "a"]
[1] 55

dt[, max(.SD), .SDcols = "a"]
[1] 10

dt[, colMeans(.SD), .SDcols = "a"]
  a 
5.5 

dt[, lapply(.SD, mean), .SDcols = "a"]
     a
1: 5.5

有趣的是,当我在 j 中使用 weighted.mean(.SD) 时,weighted.mean 给出了错误答案(总和为55)。但是,当我在 j 中使用 lapply(.SD, weighted.mean) 时,它给出了正确答案(均值为5.5)。
我尝试关闭 data.table 的优化,看看是否是内部的 data.table 平均函数的问题,但这并没有改变什么。
也许这只是在列表上使用 mean()(似乎是 .SD 返回的内容)的问题?我想除非没有使用 lapply 范例与 .SD,否则永远没有不使用 lapply 范例的理由。似乎只有 lapply 选项返回 data.table。其他选项似乎返回向量,除了 colMeans 返回其他内容(列表?)。
我的主要问题是为什么 mean(.SD) 不起作用。推论是是否可以在缺少 apply 函数之一的情况下使用 .SD。
谢谢。

6
dt[, mean(.SD[[1]]), .SDcols=a] 的意思是对于数据表 dt 中选定的列 a,计算该列的均值。其中 mean 函数适用于向量,而 .SDdata.table 的子集,仍然不是向量。你可以在 data.frame 中遇到同样的问题。例如,df1 <- data.frame(Col1=1:10); mean(df1[1]) 会出错,而 mean(df1[,1]) 则可以正常运行。 - akrun
你应该尝试使用代码块(CTRL+K或按下具有突出显示文本的代码块按钮;或在行首键入四个空格):http://stackoverflow.com/editing-help#code - Frank
@akrun:这很有趣,也很有道理。R的错误信息似乎是误导性的。它表明问题出在数据类型(数字或逻辑)上,而不是数据结构上。 - Mark Danese
1
@Frank:谢谢。那会更容易些。感谢你的帮助。 - Mark Danese
@MarkDanese 我记得在 R 邮件列表中有关于这个问题的有趣讨论,但我现在找不到链接了。 - akrun
@MarkDanese,你能否看一下提供的答案是否回答了问题?如果没有,请提供反馈;如果有,请接受它,这样问题就不会无人回答了。谢谢。 - jangorecki
1个回答

2

我认为处理你想要的内容的适当方式就是简单使用标准语法:

dt[, lapply(.SD, mean), .SDcols = "a"]

或者,你可以按照以下方式通过名称传递变量:

col_to_pass = "a"
dt[ , mean(get(col_to_pass)) ]

最终,您可以将此方法推广到多列,如下所示:
col_to_pass = c("a", "d")
dt[ , lapply( mget(col_to_pass), mean) ]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接