0

我正在尝试确定如何有效地组合列。我从一个看起来有点像下面的数据框开始。变量名称不遵循任何特定模式,并且我尝试组合的列不一定彼此相邻。我已经包含了列号,以便更容易地引用它们。

想象一下,我正在尝试合并第 2 列和第 3 列、第 4 列和第 7 列以及第 5 列和第 6 列。如您所见,如果正在合并的列之一中有一个数字,则相应的列有一个 NA。如果第 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")

有没有办法将这些组合起来,这样我就不必手动重复相同的功能来制作每一列?我还需要合并几列,所以我希望有一种更有效的方法来做到这一点。如果我能澄清任何事情,请告诉我。

4

2 回答 2

2

也许像这样使用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)
于 2018-09-13T22:54:18.403 回答
0

这比 Maurits 的解决方案要冗长得多,但它到达了同一个地方:

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
于 2018-09-13T23:02:37.820 回答