如何使用dplyr将多个列中的缺失值替换为其他值

4

我想使用当前 dplyr(1.0.2)的代码,将以v开头的列中的NA替换为列x中的值。

相同的问题在这里发帖过,但是答案已经过时了。

我能够处理一个列中的情况:

suppressMessages(library(dplyr))
df <- data.frame(v1 = c(NA, 1, 2), v2 = c(3, NA, 4), v3 = c(5, 6, NA), x = c(7, 8, 9))
df %>% mutate(v1 = coalesce(v1, x))
#>   v1 v2 v3 x
#> 1  7  3  5 7
#> 2  1 NA  6 8
#> 3  2  4 NA 9

reprex package (v0.3.0) 创建于2020年11月03日。

但是我无法弄清如何使其跨多列工作。

以下是我尝试过但没有成功的一些方法:

suppressMessages(library(dplyr))
df <- data.frame(v1 = c(NA, 1, 2), v2 = c(3, NA, 4), v3 = c(5, 6, NA), x = c(7, 8, 9))
df %>% mutate(across(starts_with("v")), . = coalesce(., x))
#> Error in list2(...): object 'x' not found

此内容由reprex包(v0.3.0)于2020年11月03日创建。

suppressMessages(library(dplyr))
df <- data.frame(v1 = c(NA, 1, 2), v2 = c(3, NA, 4), v3 = c(5, 6, NA), x = c(7, 8, 9))
df %>% mutate(across(starts_with("v")), . = coalesce(., df$x))
#> Error: Can't combine `..1` <data.frame> and `..2` <double>.

这段内容是由 reprex包 (v0.3.0) 于2020年11月03日创建的

感谢您的帮助。

1个回答

7

你非常接近across()。你想要的方法是:

df %>%
  mutate(across(starts_with("v"), coalesce, x))

注意,coalesce 函数在 across() 中使用,且 xcoalesce() 的第二个参数)可以作为第三个参数提供。结果:

  v1 v2 v3 x
1  7  3  5 7
2  1  8  6 8
3  2  4  9 9

如果您更喜欢类似于使用 coalesce(., x) 的方法,您也可以使用带有 ~ 的匿名函数来传递它:
df %>%
  mutate(across(starts_with("v"), ~ coalesce(., x)))

在其他情况下,这可能更加灵活 (例如,如果 . 不是函数的第一个参数)。

啊哈!我尝试了匿名函数的方法,但是把 ) 放错位置了——难怪我从来没能让 across() 正常工作。你们有没有关于匿名函数中使用 ..x 的想法? - jtr13
1
@jtr13 当我只有一个参数时,我使用“.”,但这并没有什么区别,我没有意见。(尽管“.x”可能会更明显地表明它不是指传递到管道中的对象) - David Robinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接