我正在尝试编写ifelse()
要传递给的专用功能dplyr::mutate(across())
。该函数应将across()
名称为的列中的NA值替换为名称相似的列中的NA值。
例如在下面的虚构的数据,我想替换丢失x_var1
与y_var1
和失踪x_var2
有y_var2
:
x <- tribble(~x_var1, ~x_var2, ~y_var1, ~y_var2,
5, 2, 0, 0,
NA, 10, 8, 0,
3, NA, 0, 5,
NA, NA, 7, 9)
我试过构造以下函数:
ifelse_spec <- function(var) {
new_var = paste("y_", str_remove(cur_column(), "x_"), sep = "")
# print(new_var) # just to check new_var is correct
ifelse(is.na(var), !!sym(new_var) , var) # how to call new_var?
}
x %>%
mutate(across(c(x_var1, x_var2),
~ ifelse_spec(.)))
但它似乎不起作用。
但是,如果我ifelse
直接使用这种单变量案例,则会得到预期的结果。
x %>%
mutate(across(c(x_var1),
~ifelse(is.na(.), !!sym("y_var1"), .)))
如何构造自定义的ifelse语句,该语句将允许我调用数据变量?
编辑:我有以下工作在多变量的情况下,但仍在使用ifelse
而不是不同的功能。
x %>%
mutate(across(c(x_var1, x_var2),
~ifelse(is.na(.), eval(sym(paste("y_", str_remove(cur_column(), "x_"), sep = ""))), . )))
coalesce()
专为解决此问题而设计(填充其他列中的缺失值)。您可以使用它来代替ifelse
:
library(dplyr, warn.conflicts = FALSE)
library(stringr)
library(purrr)
x <- tribble(~x_var1, ~x_var2, ~y_var1, ~y_var2,
5, 2, 0, 0,
NA, 10, 8, 0,
3, NA, 0, 5,
NA, NA, 7, 9)
x %>%
mutate(x_var1 = coalesce(x_var1, y_var1))
#> # A tibble: 4 x 4
#> x_var1 x_var2 y_var1 y_var2
#> <dbl> <dbl> <dbl> <dbl>
#> 1 5 2 0 0
#> 2 8 10 8 0
#> 3 3 NA 0 5
#> 4 7 NA 7 9
然后,您可以用来select()
将其概括化以在名称相似的列之间合并:
x %>%
mutate(x_var1 = do.call(coalesce, select(., ends_with("var1"))))
#> # A tibble: 4 x 4
#> x_var1 x_var2 y_var1 y_var2
#> <dbl> <dbl> <dbl> <dbl>
#> 1 5 2 0 0
#> 2 8 10 8 0
#> 3 3 NA 0 5
#> 4 7 NA 7 9
最后,使用map_dfc
将此功能应用于每列,使用模式匹配提取其所属的“列组”:
x %>%
colnames() %>%
str_extract("var[0-9]") %>%
set_names(colnames(x)) %>%
map_dfc(~do.call(coalesce, select(x, ends_with(.))))
#> # A tibble: 4 x 4
#> x_var1 x_var2 y_var1 y_var2
#> <dbl> <dbl> <dbl> <dbl>
#> 1 5 2 5 2
#> 2 8 10 8 10
#> 3 3 5 3 5
#> 4 7 9 7 9
您将需要在实际数据中调整str_extract()
和ends_with()
适应列名,但是我认为这应该推广到任何合理的命名方案。如果将自定义函数而不是应用于您的实际数据很重要coalesce()
,那么也应该可以重写map_dfc()
使用它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句