dplyr: mutate_at + coalesce: динамические имена столбцов - PullRequest
0 голосов
/ 03 марта 2019

Я некоторое время пытался объединить mutate_at с coalesce в случае, когда имена столбцов генерируются динамически.

В моем примере есть только пять столбцов, но в реальных данныхих намного больше (и не все столбцы должны быть включены в шаг coalesce).

Пример DF:

data_example <- data.frame(
  aa = c(1, NA, NA),
  bb = c(NA, NA, 2),
  cc = c(6, 7, 8),
  aa_extra = c(2, 2, NA),
  bb_extra = c(1, 2, 3)
)

Ожидаемый результат:

  aa bb cc aa_extra bb_extra
1  1  1  6        2        1
2  2  2  7        2        2
3 NA  2  8       NA        3

выходкак structure:

structure(list(aa = c(1, 2, NA), bb = c(1, 2, 2), cc = c(6, 7, 
8), aa_extra = c(2, 2, NA), bb_extra = c(1, 2, 3)), class = "data.frame", row.names = c(NA, 
-3L))

Я пробовал что-то подобное, но безуспешно («Только символы могут быть преобразованы в символы»).Я хотел бы избежать создания дополнительных переменных, просто включите все в выражение mutate_at, так как это часть более длинного dplyr-потока.

data_example %>%
  dplyr::mutate_at(
    gsub("_extra", "", grep("_extra$",
                            colnames(.),
                            perl = T,
                            value = T)),
    dplyr::funs(
      dplyr::coalesce(., !!! dplyr::sym(paste0(., "_extra")))
    )
  )

Я пробовал также это (без ошибок,но значения для столбца bb неверны):

data_example %>%
  dplyr::mutate_at(
    gsub("_extra", "", grep("_extra$",
                            colnames(.),
                            perl = T,
                            value = T)),
    dplyr::funs(
      dplyr::coalesce(., !!as.name(paste0(names(.), "_extra")))
    )
  )

Как получить имя обработанного столбца и передать его coalesce?

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Использование data.table для melt и dcast, поскольку я никогда не могу вспомнить, как spread и gather работают

library(data.table)
library(dplyr)

data_example %>% 
  mutate(row = row_number()) %>% 
  melt('row') %>% 
  group_by(g = sub('_*$', '', variable), row) %>% 
  mutate(value = reduce(value, coalesce)) %>% 
  dcast(row ~ variable) %>% 
  select(-row)

#   aa bb cc aa_extra bb_extra
# 1  1  1  6        1        1
# 2  2  2  7        2        2
# 3 NA  2  8       NA        2
0 голосов
/ 03 марта 2019

Мы можем split набор данных в list data.frames после удаления подстроки имен столбцов ("_extra"), затем с помощью map перебрать list, coalesce столбец изатем bind со столбцами "_extra" в исходном наборе данных

library(tidyverse)
data_example %>% 
   split.default(str_remove(names(.), "_extra")) %>%
   map_df(~ coalesce(!!! .x)) %>%
   #or use
   # map_df(reduce, coalesce) %>%
   bind_cols(., select(data_example, ends_with("extra")))
# A tibble: 3 x 5
#     aa    bb    cc aa_extra bb_extra
#  <dbl> <dbl> <dbl>    <dbl>    <dbl>
#1     1     1     6        2        1
#2     2     2     7        2        2
#3    NA     2     8       NA        3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...