[英]data.table: How do I pass a character vector to a function get data.table to treat its contents as column names?
這是一個數據表:
library(data.table)
DT <- data.table(airquality)
這個例子產生了我想要的輸出:
DT[, `:=`(New_Ozone= log(Ozone), New_Wind=log(Wind))]
如何編寫函數log_those_columns
以便以下代碼片段輸出相同的結果?
old_names <- c("Ozone", "Wind")
new_names <- c("New_Ozone", "New_Wind")
log_those_columns(DT, old_names, new_names)
請注意,我需要old_names
和new_names
足夠靈活以包含任意數量的列。
(我從關於這個主題的類似 StackOverflow 問題中看到,答案可能涉及.SD
、 with=F
、 parse()
、 eval()
和/或substitute()
某種組合,但我似乎無法確定哪個要使用的那些以及在哪里)。
拿起MichaelChirico 的評論,函數定義可以寫成:
log_those_columns <- function(DT, cols_in, cols_new) {
DT[, (cols_new) := lapply(.SD, log), .SDcols = cols_in]
}
返回:
log_those_columns(DT, old_names, new_names)
DT
Ozone Solar.R Wind Temp Month Day New_Ozone New_Wind 1: 41 190 7.4 67 5 1 3.713572 2.001480 2: 36 118 8.0 72 5 2 3.583519 2.079442 3: 12 149 12.6 74 5 3 2.484907 2.533697 4: 18 313 11.5 62 5 4 2.890372 2.442347 5: NA NA 14.3 56 5 5 NA 2.660260 --- 149: 30 193 6.9 70 9 26 3.401197 1.931521 150: NA 145 13.2 77 9 27 NA 2.580217 151: 14 191 14.3 75 9 28 2.639057 2.660260 152: 18 131 8.0 76 9 29 2.890372 2.079442 153: 20 223 11.5 68 9 30 2.995732 2.442347
正如預期的那樣。
用於轉換數據的函數也可以作為參數傳遞:
fct_those_columns <- function(DT, cols_in, cols_new, fct) {
DT[, (cols_new) := lapply(.SD, fct), .SDcols = cols_in]
}
電話:
fct_those_columns(DT, old_names, new_names, log)
head(DT)
按預期工作:
Ozone Solar.R Wind Temp Month Day New_Ozone New_Wind 1: 41 190 7.4 67 5 1 3.713572 2.001480 2: 36 118 8.0 72 5 2 3.583519 2.079442 3: 12 149 12.6 74 5 3 2.484907 2.533697 4: 18 313 11.5 62 5 4 2.890372 2.442347 5: NA NA 14.3 56 5 5 NA 2.660260 6: 28 NA 14.9 66 5 6 3.332205 2.701361
函數名可以作為字符傳遞:
fct_those_columns(DT, old_names, new_names, "sqrt")
head(DT)
Ozone Solar.R Wind Temp Month Day New_Ozone New_Wind 1: 41 190 7.4 67 5 1 6.403124 2.720294 2: 36 118 8.0 72 5 2 6.000000 2.828427 3: 12 149 12.6 74 5 3 3.464102 3.549648 4: 18 313 11.5 62 5 4 4.242641 3.391165 5: NA NA 14.3 56 5 5 NA 3.781534 6: 28 NA 14.9 66 5 6 5.291503 3.860052
或作為匿名函數:
fct_those_columns(DT, old_names, new_names, function(x) x^(1/2))
head(DT)
Ozone Solar.R Wind Temp Month Day New_Ozone New_Wind 1: 41 190 7.4 67 5 1 6.403124 2.720294 2: 36 118 8.0 72 5 2 6.000000 2.828427 3: 12 149 12.6 74 5 3 3.464102 3.549648 4: 18 313 11.5 62 5 4 4.242641 3.391165 5: NA NA 14.3 56 5 5 NA 3.781534 6: 28 NA 14.9 66 5 6 5.291503 3.860052
下面的函數通過自動在輸入列的名稱前面加上函數的名稱來派生新列的名稱:
fct_those_columns <- function(DT, cols_in, fct) {
fct_name <- substitute(fct)
cols_new <- paste(if (class(fct_name) == "name") fct_name else fct_name[3], cols_in, sep = "_")
DT[, (cols_new) := lapply(.SD, fct), .SDcols = cols_in]
}
DT <- data.table(airquality)
fct_those_columns(DT, old_names, sqrt)
fct_those_columns(DT, old_names, data.table::as.IDate)
fct_those_columns(DT, old_names, function(x) x^(1/2))
DT
Ozone Solar.R Wind Temp Month Day sqrt_Ozone sqrt_Wind as.IDate_Ozone as.IDate_Wind x^(1/2)_Ozone x^(1/2)_Wind 1: 41 190 7.4 67 5 1 6.403124 2.720294 1970-02-11 1970-01-08 6.403124 2.720294 2: 36 118 8.0 72 5 2 6.000000 2.828427 1970-02-06 1970-01-09 6.000000 2.828427 3: 12 149 12.6 74 5 3 3.464102 3.549648 1970-01-13 1970-01-13 3.464102 3.549648 4: 18 313 11.5 62 5 4 4.242641 3.391165 1970-01-19 1970-01-12 4.242641 3.391165 5: NA NA 14.3 56 5 5 NA 3.781534 <NA> 1970-01-15 NA 3.781534 --- 149: 30 193 6.9 70 9 26 5.477226 2.626785 1970-01-31 1970-01-07 5.477226 2.626785 150: NA 145 13.2 77 9 27 NA 3.633180 <NA> 1970-01-14 NA 3.633180 151: 14 191 14.3 75 9 28 3.741657 3.781534 1970-01-15 1970-01-15 3.741657 3.781534 152: 18 131 8.0 76 9 29 4.242641 2.828427 1970-01-19 1970-01-09 4.242641 2.828427 153: 20 223 11.5 68 9 30 4.472136 3.391165 1970-01-21 1970-01-12 4.472136 3.391165
請注意, x^(1/2)_Ozone
在 R 中不是語法上有效的名稱,需要放在反引號中:
DT$`x^(1/2)_Ozone`
你只需要寫一個函數:
log_those_columns <- function(D,old_names,new_names)
DT[,(new_names) := lapply(mget(old_names),log)]
log_those_columns(DT,old_names,new_names)
DT
Ozone Solar.R Wind Temp Month Day New_Ozone New_Wind
1: 41 190 7.4 67 5 1 3.713572 2.001480
2: 36 118 8.0 72 5 2 3.583519 2.079442
3: 12 149 12.6 74 5 3 2.484907 2.533697
4: 18 313 11.5 62 5 4 2.890372 2.442347
5: NA NA 14.3 56 5 5 NA 2.660260
---
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.