2014-10-10 12 views
1

如果我將變量bloodpressure傳遞給data.table,一切正常。爲什麼data.table分組取決於我是否直接將變量名稱傳遞給它?

tdt <- data.table(bloodpressure = rnorm(1000, mean=100, sd=15), male=rep(c(0,1))) 
strata.var <- with(tdt, get(c('male'))) 

tdt[,list(
      varname='bloodpressure', 
      N=.N, 
      mean=mean(bloodpressure, na.rm=TRUE), 
      sd=sd(bloodpressure, na.rm=TRUE) 
      ), 
     by=(strata.var)] 

我得到這樣的結果

strata.var  varname N  mean  sd 
1:   0 bloodpressure 500 100.2821 15.13686 
2:   1 bloodpressure 500 100.0392 15.02566 

相匹配的組是指

> mean(tdt$bloodpressure[tdt$male==0]) 
[1] 100.2821 
> mean(tdt$bloodpressure[tdt$male==1]) 
[1] 100.0392 

但是,如果我想以編程方式做到這一點,變量保存在另一個變量(var

var_as_string <- 'bloodpressure' 
var <- with(tdt, get(var_as_string)) 

tdt[,list(
      varname='bloodpressure', 
      N=.N, 
      mean=mean(var, na.rm=TRUE), 
      sd=sd(bloodpressure, na.rm=TRUE) 
      ), 
     by=(strata.var)] 

我得到了不同的結果。

strata.var  varname N  mean  sd 
1:   0 bloodpressure 500 100.1606 15.13686 
2:   1 bloodpressure 500 100.1606 15.02566 

注意,現在mean是相同的(即不按組在整個樣本來計算。

> mean(tdt$bloodpressure) 
[1] 100.1606 
+0

@Arun我不認爲我理解範圍界定問題......我已將'bloodpressure'分配給'var',但這顯然是不正確的/不足的,data.table'只能看到' var'。我會做更多的閱讀...;) – drstevok 2014-10-10 15:07:58

+0

我還不確定,但我想你可能在這裏發現了一個錯誤..測試。將回寫:-)。 – Arun 2014-10-10 15:18:58

+0

是的,這是一個錯誤,正如我懷疑的那樣。提交[#875](https://github.com/Rdatatable/data.table/issues/875)。謝謝! – Arun 2014-10-10 15:53:02

回答

1

確定。從this excellent post幫助,我想我有答案...

colVars <- c('bloodpressure') 
byCols <- c('male') 
tdt[, lapply(.SD, function(x) mean=mean(x)), .SDcols = colVars, by=byCols] 
tdt[, list(
    mean = lapply(.SD, function(x) mean(x)), 
    sd = lapply(.SD, function(x) sd(x)) 
    ), .SDcols = colVars, by=byCols] 

訣竅是使用.SD,.SDcols,並將所有東西都包裹在lapply

爲什麼它,儘管尋找年齡,它只是花了另一個時間塊起草一個問題,我設法找到答案後?一種https://meta.stackoverflow.com/問題...

2

您可以替換mean=mean(var, na.rm=TRUE),mean=mean(get(var_as_string), na.rm=TRUE),然後它應該工作 - 否則它只是使用數字矢量var而不是你想要它使用的數據表的字段(和兩個亞組返回mean(var) )。

library(data.table) 
set.seed(1) 
tdt <- data.table(bloodpressure = rnorm(1000, mean=100, sd=15), male=rep(c(0,1))) 
strata.var <- with(tdt, get(c('male'))) 

tdt[,list(
     varname='bloodpressure', 
     N=.N, 
     mean=mean(bloodpressure, na.rm=TRUE), 
     sd=sd(bloodpressure, na.rm=TRUE) 
     ), 
    by=(strata.var)]   
# strata.var  varname N  mean  sd 
#1:   0 bloodpressure 500 99.58425 15.55735 
#2:   1 bloodpressure 500 100.06630 15.50188 

var_as_string <- 'bloodpressure' 

tdt[,list(
     varname='bloodpressure', 
     N=.N, 
     mean=mean(get(var_as_string), na.rm=TRUE), 
     sd=sd(bloodpressure, na.rm=TRUE) 
     ), 
    by=(strata.var)]     
# strata.var  varname N  mean  sd 
#1:   0 bloodpressure 500 99.58425 15.55735 
#2:   1 bloodpressure 500 100.06630 15.50188 
+0

這不是我知道的更好,但是這比我遇到並在下面發佈的'.SDcols'方法更適合嗎? – drstevok 2014-10-10 15:16:37

+0

對於一個它似乎更直接,所以我更喜歡這一點。我只是比較速度,它似乎也稍微快一點,但我只是選擇任何語法似乎更容易... – konvas 2014-10-10 15:27:45

+0

乾杯。我已經轉向'.SDcols'方法,因爲它似乎更好地概括了 - 至少在我手中;) - 並修復了我用'by'子句處理的類似問題。 – drstevok 2014-10-10 15:33:07

相關問題