迭代 dplyr::coalesce()

Iteratively dplyr::coalesce()

我有一个数据集需要在 dplyr::coalesce() 上使用。但我想多次执行此操作,但不确定执行此操作的更有效方法是什么(例如循环、应用等)。

举个小例子,假设我的数据集是:

df = data.frame(
    a = c(1, NA, NA),
    a.1 = c(NA, 1, NA),
    a.2 = c(NA, NA, 1),
    b = c(2, NA, NA),
    b.1 = c(NA, 2, NA),
    b.2 = c(NA, NA, 2),
    c = c(3, NA, NA),
    c.1 = c(NA, 3, NA),
    c.2 = c(NA, NA, 3)
)

我可以这样做:

new_df = df |>
    dplyr::mutate(
        a = dplyr::coalesce(a, a.1, a.2),
        b = dplyr::coalesce(b, b.1, b.2),
        c = dplyr::coalesce(c, c.1, c.2)
    ) |>
    dplyr::select(a, b, c)

哪个会给我:

new_df
  a b c
1 1 2 3
2 1 2 3
3 1 2 3

首先,我怎样才能有效地做到这一点而不必编写 coalesce n 次?这个例子只是一个例子,我真的需要用数据集做四十次。

另外,有没有办法做到这一点,就像我在这里基本上只保留 a、b 和 c 而不是将其命名为 a.1 或其他名称一样?

如果列像 somethingsomthing.etc 形状,

你可以试试

library(dplyr)
library(stringr)
df %>%
  split.default(str_remove(names(.), "\..*")) %>%
  map_df(~ coalesce(!!! .x))

      a     b     c
  <dbl> <dbl> <dbl>
1     1     2     3
2     1     2     3
3     1     2     3

这是一个旋转的替代方案:

library(dplyr)
library(tidyr)

df %>% 
  pivot_longer(everything()) %>% 
  mutate(name = sub("\..*", "", name)) %>% 
  drop_na %>% 
  pivot_wider(names_from = name, values_from = value, values_fn = list) %>% 
  unnest(cols = c(a, b, c))
      a     b     c
  <dbl> <dbl> <dbl>
1     1     2     3
2     1     2     3
3     1     2     3