data.table一次计算几列

Mah*_*iha 8 r data.table

提前感谢您阅读本文.我有一个在data.table 1.9.3上工作正常的函数.但今天我更新了我的data.table包,我的功能不起作用.

这是我在data.table 1.9.3上的函数和工作示例:

trait.by <- function(data,traits="",cross.by){
  traits = intersect(traits,names(data))
  if(length(traits)<1){  
    #if there is no intersect between names and traits
    return(      data[,       list(N. = .N),    by=cross.by])
  }else{
    return(data[,c(   N. = .N,
                    MEAN = lapply(.SD,function(x){return(round(mean(x,na.rm=T),digits=1))}) , 
                    SD   = lapply(.SD,function(x){return(round(sd  (x,na.rm=T),digits=2))}) ,
                    'NA' = lapply(.SD,function(x){return(sum  (is.na(x)))})),
                 by=cross.by, .SDcols = traits])
  }
}

> trait.by(data.table(iris),traits = c("Sepal.Length",    "Sepal.Width"),cross.by="Species")
#      Species N. MEAN.Sepal.Length MEAN.Sepal.Width SD.Sepal.Length
#1:     setosa 50               5.0              3.4            0.35
#2: versicolor 50               5.9              2.8            0.52
#3:  virginica 50               6.6              3.0            0.64
#   SD.Sepal.Width NA.Sepal.Length NA.Sepal.Width
#1:           0.38               0              0
#2:           0.31               0              0
#3:           0.32               0              0
Run Code Online (Sandbox Code Playgroud)

问题的关键是MEAN.(traits),SD.(traits)NA.(traits)计算了,我给所有列traits变量.


当我使用data.table 1.9.4运行它时,我收到以下错误:

> trait.by(data.table(iris),traits = c("Sepal.Length",    "Sepal.Width"),cross.by="Species")
#Error in assign("..FUN", eval(fun, SDenv, SDenv), SDenv) : 
#  cannot change value of locked binding for '..FUN'
Run Code Online (Sandbox Code Playgroud)

知道我应该怎么解决这个问题?!

Bro*_*ieG 4

更新:此问题现已在1.9.5的commit 1680中修复。来自新闻

  1. j-expression修复了多个内部优化中的错误,lapply(.SD, function(..) ..)SO 所示。关闭#985。感谢@jadaliha 的报告和@BrodieG 对SO 的调试。

现在这按预期工作:

data[,
  c(
    MEAN = lapply(.SD,function(x){return(round(mean(x,na.rm=T),digits=1))}),
    SD = lapply(.SD,function(x){return(round(sd  (x,na.rm=T),digits=2))})
  ), by=cross.by, .SDcols = traits]    
Run Code Online (Sandbox Code Playgroud)

这看起来像是一个错误,是由于lapply(.SD, FUN)在一次data.table调用中多次使用 与c(. c(您可以通过替换为来解决这个问题.(

traits <- c("Sepal.Length",    "Sepal.Width")
cross.by <- "Species"
data <- data.table(iris)

data[,
  c(
    MEAN = lapply(.SD,function(x){return(round(mean(x,na.rm=T),digits=1))})
  ),
  by=cross.by, .SDcols = traits
]
Run Code Online (Sandbox Code Playgroud)

作品。

data[,
  c(
    SD = lapply(.SD,function(x){return(round(sd  (x,na.rm=T),digits=2))})
  ),
  by=cross.by, .SDcols = traits
]
Run Code Online (Sandbox Code Playgroud)

作品。

data[,
  c(
    MEAN = lapply(.SD,function(x){return(round(mean(x,na.rm=T),digits=1))}),
    SD = lapply(.SD,function(x){return(round(sd  (x,na.rm=T),digits=2))})
  ),
  by=cross.by, .SDcols = traits
]    
Run Code Online (Sandbox Code Playgroud)

不起作用

data[,
  .(
    MEAN = lapply(.SD,function(x){return(round(mean(x,na.rm=T),digits=1))}),
    SD = lapply(.SD,function(x){return(round(sd  (x,na.rm=T),digits=2))})
  ),
  by=cross.by, .SDcols = traits
]
Run Code Online (Sandbox Code Playgroud)

作品。