簡體   English   中英

將多個列名傳遞給 data.table 函數中的“by”

[英]Passing multiple column names to "by" in a data.table function

我已經閱讀了很多關於將列名傳遞給 data.table 函數的帖子,但我沒有看到處理將多個變量傳遞給“by”的帖子。 我通常使用這樣的代碼來按組計算匯總統計數據。

# Data
library(data.table)
dt=mtcars
setDT(dt)

# Summary Stats Example
dt[cyl==4,.(Count=.N,
    Mean=mean(hp),
    Median=median(hp)),
    by=.(am,vs)]

#    am vs Count   Mean Median
# 1:  1  1     7 80.571     66
# 2:  0  1     3 84.667     95
# 3:  1  0     1 91.000     91

我無法使用以下功能:

# Function
myFun <- function(df,i,j,by){
    df[i==4,.(Count=.N,
      Mean=mean(j),
      Median=median(j)),
      by=.(am,by)]
}
myFun(dt,i='cyl',j='hp',by='vs')

請注意,我將“4”和“am”硬編碼到此示例的函數中。 get()在僅通過分組變量使用 1 時有效,但在使用多個分組變量時失敗。 感謝有關在編寫 data.table 函數時如何正確使用 get/quote/eval/substitute/parse/as.name/etc 的指導。

只需為data.table by一部分創建一個字符向量,它就會起作用:

myFun <- function(df, i, j, by){

 df[get(i) == 4, .(Count = .N, 
           Mean = mean(get(j)),
           Median = median(get(j))),
  by = c(by, 'am')]
}



myFun(dt, i = 'cyl', j = 'hp', by = 'vs')

#vs am Count     Mean Median
#1:  1  1     7 80.57143     66
#2:  1  0     3 84.66667     95
#3:  0  1     1 91.00000     91

我已經接受了 sm95 的回答。 下面是一個更復雜的示例/解決方案,它將列表發送到by參數:

# Libraries
library(data.table)

# Data
dt = mtcars
setDT(dt)

# Function to calculate summary statistics
myFun <- function(df, i1var, i1val, i2var, i2val,            # i arguments
                                    j,                       # j arguments
                                    by1var, by2var, by2val){ # by arguments
    df[get(i1var) == i1val & get(i2var) %in% i2val,
         .(Count = .N,
            Mean = mean(get(j)),
            Median = median(get(j))),
        by = .(get(by1var), get(by2var) == by2val)]
} # END Function

# Run function
myFun(dt,i1var = 'cyl', i1val = 4, i2var = 'gear', i2val = c(3,4),
            j = 'hp',
            by1var = 'vs', by2var = 'am', by2val = 1)
#    vs am Count     Mean Median
# 1:  1  1     6 75.16667     66
# 2:  1  0     3 84.66667     95

# Should match
dt[cyl == 4 & gear %in% c(3,4),
     .(Count = .N,
        Mean = mean(hp),
        Median = median(hp)),
     by = .(vs, am == 1)]
#    vs am Count     Mean Median
# 1:  1  1     6 75.16667     66
# 2:  1  0     3 84.66667     95

這是我的備忘單:

  • 使用get(var)傳遞ijby變量
  • 通過i或直接by標准

以上可能不適用於更復雜的功能,並且可能不是最優的。

如果by是向量而不是列表(例如, by=c()by=.() ),則可以直接傳遞by參數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM