fcase到多个输出
fcase to multiple outputs
假设以下 table:
data <- data.table(dummy=1:10)
我知道你可以做以下事情:
data[dummy < 5, c("test1", "test2") := list("Yes", 1)]
和:
data[, test1 := fcase(dummy < 5, "Yes")]
data[, test2 := fcase(dummy < 5, 1)]
我正在尝试将它们合二为一:
data[, c("test1", "test2") := fcase(dummy < 5, list("Yes", 1))]
但它给我以下错误:
Error in fcase(dummy < 5, list("Yes", 1)) :
Length of output value #2 must either be 1 or length of logical condition.
我需要通过多个过滤器,所以使用 fcase
很有意义。我总是可以像这样对每个过滤器使用第一个解决方案:
data[dummy < 5, c("test1", "test2") := list("Yes", 1)]
data[dummy > 7, c("test1", "test2") := list("No", 0)]
data[between(dummy, 5, 7), c("test1", "test2") := list("Maybe", NA)]
但我想知道是否还有更多可能。还有一个解决方案是用 test1
和 test2
的每个组合创建一个 table 并在执行 [=17= 之后将此 table 与数据 table 合并] 仅 test1
像这样:
tests <- data.table(test1 = c("Yes", "No", "Maybe"),
test2 = c(1, 0, NA))
data[, test1 := fcase(dummy < 5, "Yes",
dummy > 7, "No",
between(dummy, 5, 7), NA_character_)]
merge(data, tests, by = "test1", all.x = T, sort = F)
但这对于庞大而复杂的数据来说似乎效率低下table
与rbindlist
:
data[, c("test1", "test2") := rbindlist(fcase(dummy < 5, .(.("Yes", 1)),
dummy > 7, .(.("No", 0)),
default = .(.("Maybe", NA))))]
data
#> dummy test1 test2
#> 1: 1 Yes 1
#> 2: 2 Yes 1
#> 3: 3 Yes 1
#> 4: 4 Yes 1
#> 5: 5 Maybe NA
#> 6: 6 Maybe NA
#> 7: 7 Maybe NA
#> 8: 8 No 0
#> 9: 9 No 0
#> 10: 10 No 0
do.call
将允许您将 fcase
条件放入一个列表中,并将值放入另一个嵌套列表列表中:
data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7),
.(.(.("Yes", 1)), .(.("Maybe", NA)), .(.("No", 0))))))]
或者以 tests
为例:
tests <- data.table(test1 = c("Yes", "Maybe", "No"),
test2 = c(1, NA, 0))
tests[, val := .(.(.(.SD))), by = 1:nrow(tests)]
data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7), tests$val)))]
假设以下 table:
data <- data.table(dummy=1:10)
我知道你可以做以下事情:
data[dummy < 5, c("test1", "test2") := list("Yes", 1)]
和:
data[, test1 := fcase(dummy < 5, "Yes")]
data[, test2 := fcase(dummy < 5, 1)]
我正在尝试将它们合二为一:
data[, c("test1", "test2") := fcase(dummy < 5, list("Yes", 1))]
但它给我以下错误:
Error in fcase(dummy < 5, list("Yes", 1)) :
Length of output value #2 must either be 1 or length of logical condition.
我需要通过多个过滤器,所以使用 fcase
很有意义。我总是可以像这样对每个过滤器使用第一个解决方案:
data[dummy < 5, c("test1", "test2") := list("Yes", 1)]
data[dummy > 7, c("test1", "test2") := list("No", 0)]
data[between(dummy, 5, 7), c("test1", "test2") := list("Maybe", NA)]
但我想知道是否还有更多可能。还有一个解决方案是用 test1
和 test2
的每个组合创建一个 table 并在执行 [=17= 之后将此 table 与数据 table 合并] 仅 test1
像这样:
tests <- data.table(test1 = c("Yes", "No", "Maybe"),
test2 = c(1, 0, NA))
data[, test1 := fcase(dummy < 5, "Yes",
dummy > 7, "No",
between(dummy, 5, 7), NA_character_)]
merge(data, tests, by = "test1", all.x = T, sort = F)
但这对于庞大而复杂的数据来说似乎效率低下table
与rbindlist
:
data[, c("test1", "test2") := rbindlist(fcase(dummy < 5, .(.("Yes", 1)),
dummy > 7, .(.("No", 0)),
default = .(.("Maybe", NA))))]
data
#> dummy test1 test2
#> 1: 1 Yes 1
#> 2: 2 Yes 1
#> 3: 3 Yes 1
#> 4: 4 Yes 1
#> 5: 5 Maybe NA
#> 6: 6 Maybe NA
#> 7: 7 Maybe NA
#> 8: 8 No 0
#> 9: 9 No 0
#> 10: 10 No 0
do.call
将允许您将 fcase
条件放入一个列表中,并将值放入另一个嵌套列表列表中:
data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7),
.(.(.("Yes", 1)), .(.("Maybe", NA)), .(.("No", 0))))))]
或者以 tests
为例:
tests <- data.table(test1 = c("Yes", "Maybe", "No"),
test2 = c(1, NA, 0))
tests[, val := .(.(.(.SD))), by = 1:nrow(tests)]
data[, c("test1", "test2") := rbindlist(do.call(fcase, rbind(.(dummy < 5, dummy <= 7, dummy > 7), tests$val)))]