Объединение нескольких пар столбцов (содержащих числа и NA) одновременно в R - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь определить, как эффективно комбинировать столбцы. Я начал с фрейма данных, который выглядит примерно так: Имена переменных не следуют какой-либо определенной схеме, и столбцы, которые я пытаюсь объединить, не обязательно находятся рядом друг с другом. Я включил номера столбцов, чтобы было легче обращаться к ним.

Представьте, что я пытаюсь объединить столбцы 2 и 3, столбцы 4 и 7 и столбцы 5 и 6. Как вы можете видеть, если в одном из столбцов, которые объединяются, есть число, то соответствующий столбец имеет Анна. Если столбец 8 == a, столбец 2 - это число, а столбец 3 - это NA. Если столбец 8 == b, столбец 2 - NA, а столбец 3 - число. Аналогичная картина следует для столбцов 9 (которые отображаются на 4 и 7) и 10 (которые отображаются на 5 и 6).

1     2      3      4     5     6     7     8     9     10

id    ab_1   ab2_1  dc_3  de_4  ze37  uh44  fac1  fac2  fac3
1     2      NA     NA    4     NA    5     a     c     e
2     NA     4      NA    NA    1     3     b     c     f
3     NA     7      2     5     NA    NA    b     d     e
4     5      NA     3     NA    7     NA    a     d     f 

Я пытаюсь создать 3 новых столбца: один с объединенными значениями для 2 и 3, один с объединенными значениями для 4 и 7 и один с объединенными значениями для 5 и 6. Я хотел бы, чтобы они были добавлены в конец датафрейм выше, и мне все равно, если исходные столбцы, которые объединяются, остаются в фрейме данных. Вот как должны выглядеть дополнительные 3 столбца:

col1  col2  col3
2     5     4
4     3     1
7     2     5
5     3     7

Вот как я это делал до сих пор:

df <- df %>%    ## combining columns 2 and 3
      gather(., 'ab_1', 'ab2_1', key = "key", value = "col1") %>%
      filter(., fac1 == "a" & key == "ab1_1" | fac1 == "b" & key == "ab2_1")

df <- df %>%    ## combining columns 4 and 7
      gather(., 'dc_3', 'uh44', key = "key2", value = "col2") %>%
      filter(., fac2 == "c" & key2 == "uh44" | 
                fac2 == "d" & key2 == "dc_3")

df <- df %>%    ## combining columns 5 and 6
      gather(., 'de_4', 'ze37', key = "key3", value = "col3") %>%
      filter(., fac3 == "e" & key == "de_4" | fac3 == "f" & key == "ze37")

Есть ли способ объединить их, чтобы мне не пришлось вручную повторять одни и те же функции для создания каждого дополнительного столбца? Мне нужно объединить еще несколько столбцов, поэтому я надеюсь, что есть более эффективный способ сделать это. Пожалуйста, дайте мне знать, если я могу уточнить что-нибудь.

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Это гораздо более многословно, чем решение Маврикия, но оно попадает в то же место:

library(tidyverse)
col_grps <- tibble(col = colnames(df),
                   group = c(NA, 1, 1, 2, 3, 3, 2, NA, NA, NA))

output <- df %>%
  gather(col, value, -id) %>%
  left_join(col_grps) %>%
  mutate(value = value %>% as.numeric) %>%
  group_by(id, group) %>%
  summarise(sums = sum(value, na.rm = TRUE)) %>% ungroup() %>%
  spread(group, sums) %>%
  select(-id, -`<NA>`)

output
# A tibble: 4 x 3
    `1`   `2`   `3`
  <dbl> <dbl> <dbl>
1     2     5     4
2     4     3     1
3     7     2     5
4     5     3     7
0 голосов
/ 14 сентября 2018

Возможно, что-то подобное, используя dplyr::coalesce?

# Define the pairs
prs <- list(col1 = c(2, 3), col2 = c(4, 7), col3 = c(5, 6))

library(tidyverse)
imap_dfc(prs, ~df[, .x] %>% transmute(!!.y := coalesce(!!!syms(names(df)[.x]))))
#  col1 col2 col3
#1    2    5    4
#2    4    3    1
#3    7    2    5
#4    5    3    7

Пример данных

df <- read.table(text =
    "id    ab_1   ab2_1  dc_3  de_4  ze37  uh44  fac1  fac2  fac3
1     2      NA     NA    4     NA    5     a     c     e
2     NA     4      NA    NA    1     3     b     c     f
3     NA     7      2     5     NA    NA    b     d     e
4     5      NA     3     NA    7     NA    a     d     f ", header = T)
...