一次在R中组合多个列

时间:2018-02-07 17:29:33

标签: r loops for-loop

我有一个类似于以下内容的数据框:

A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq
1          2        1        NA         NA       NA
NA         NA       NA       4          1        2
2          4        7        NA         NA       NA

我想制作组合A值和C值的其他列。生成的数据框将包含类似于B1U_sweet和B2F_dip的列。

A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq  B1U_sweet  B2F_dip
1          2        1        NA         NA       NA       1          2
NA         NA       NA       4          1        2        4          1
2          4        7        NA         NA       NA       2          4

有没有办法让我创建这些额外的列,而不是逐个组合A和C列?在过去,我将它们各自单独组合在一起,但如果有类似于与A1和C1,A2和C2等列相匹配的循环,那就太棒了。有20个“A”列和20个“C”列我想合并成“B”列。

编辑:解决方案是接受的答案:Combining columns in R based on matching beginnings of column title names

2 个答案:

答案 0 :(得分:0)

你可以这样做:

types <- grep('^A', names(df)) ## Get all "A" patterns
types <- substr(types, 2, Inf) ## Remove the "A"
for (tp in types) {
  aa <- df[[paste0('A', tp)]] ## "A" column
  cc <- df[[paste0('C', tp)]] ## "C" column
  df[[paste0('B', tp)]] <- ifelse(is.na(aa), aa, cc)
}

编辑:如果你的df中的其他一些列以A开头,你可以尝试以下三种方法之一:

  1. 首先从df中删除它们

  2. 不要grep这些类型,而是手动输入它们(例如types <- c("1U_sweet", ...)

  3. 如果您的类型遵循特定模式,则可以将grep中的正则表达式更改为"^A[0-9][0-9][A-Z]_[a-z]+"

答案 1 :(得分:0)

不使用循环的dplyr方法:

df = read.table(text = "
A1U_sweet  A2F_dip  A3U_bbq  C1U_sweet  C2F_dip  C3U_bbq
1          2        1        NA         NA       NA
NA         NA       NA       4          1        2
2          4        7        NA         NA       NA
", header=T)

library(tidyverse)

df %>%
  mutate(row_id = row_number()) %>%
  gather(col,value,-row_id) %>%
  mutate(col1 = substr(col, 1, 1),
         col2 = substr(col, 2, nchar(col))) %>%
  group_by(row_id, col2) %>%
  summarise(new_value = unique(value[!is.na(value)])) %>%
  ungroup() %>%
  mutate(col2 = paste0("B",col2)) %>%
  spread(col2,new_value) %>%
  bind_cols(df) %>%
  select(-row_id, -B3U_bbq)

# # A tibble: 3 x 8
#   B1U_sweet B2F_dip A1U_sweet A2F_dip A3U_bbq C1U_sweet C2F_dip C3U_bbq
#       <int>   <int>     <int>   <int>   <int>     <int>   <int>   <int>
# 1         1       2         1       2       1        NA      NA      NA
# 2         4       1        NA      NA      NA         4       1       2
# 3         2       4         2       4       7        NA      NA      NA