[英]R data.table assign two columns by reference using ifelse
我有以下 data.table
library(data.table)
x <- data.table(a = 1:3, b = 1:6)
我想通過引用同時分配兩列,因為兩列使用相同類型的檢查。 通常我會這樣做:( 在 data.table 中使用:= 按組分配多個列)
x[, c("col1", "col2") := list("Yes", b)]
但我需要一個ifelse
結構。 所以我嘗試了:
x[, c("col1", "col2") := ifelse(a > 2, list("Yes", b), list("No", a))]
但這不起作用,我得到一個錯誤:
Supplied 2 columns to be assigned 6 items
我該如何解決?
你可以:
x[, c("col1", "col2") := .("No", a)] # Default value
x[a > 2, c("col1", "col2") := .("Yes", b)] # .() is short for list()
另一種可以更好地推廣到更復雜情況的選擇:
x[, test_a := a > 2]
update_table <- data.table(
test_a = c(TRUE, FALSE),
col1 = c('Yes', 'No'),
col2 = c('a', 'b')
)
cols <- c('col1', 'col2')
x[, (cols) := update_table[.SD, on = 'test_a', .SD, .SDcols = cols]]
您可以嘗試使用if... else...
下面的代碼,而不是ifelse()
x <- data.table(a = 1:3, b = 1:6)
x[,
c("col1", "col2") :={
if (a > 2) list("Yes", b) else list("No", a)
},
by = 1:nrow(x)
][]
這使
a b col1 col2
1: 1 1 No 1
2: 2 2 No 2
3: 3 3 Yes 3
4: 1 4 No 1
5: 2 5 No 2
6: 3 6 Yes 6
我的實際數據包含一個更復雜的ifelse
語句(超過 2 個案例),我解決該問題的方法是將分配拆分如下:
# Assign first col1
x[, col1 := ifelse(a > 2, "Yes", "No")]
# Based on col1 assign col2
col1_mapper = c("Yes" = "a", "No" = "b")
x[, col2 := get(col1_mapper[col1])]
另一種方法,如果您想以不同的方式指定返回值。 請注意,在基准測試中,沒有一個提議的解決方案能勝過ifelse
方法的兩倍,因為檢查並不昂貴。 對於您的實際數據,您可以嘗試
mif <- function(x, ...){
Vectorize(\(x, a, b) if(x) list(..3, b) else list(..4, a))(x, ..1, ..2) |>
(\(.) list(unlist(.[1,], use.names = F), unlist(.[2,], use.names = F)))()
}
x <- data.table(a = 1:3, b = 1:6)
x[, c("col1", "col2") := mif(a > 2, a, b, "Yes", "No")]
x
a b col1 col2
1: 1 1 No 1
2: 2 2 No 2
3: 3 3 Yes 3
4: 1 4 No 1
5: 2 5 No 2
6: 3 6 Yes 6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.