我有一个类似于以下内容的数据框:
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
答案 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开头,你可以尝试以下三种方法之一:
首先从df中删除它们
不要grep这些类型,而是手动输入它们(例如types <- c("1U_sweet", ...)
如果您的类型遵循特定模式,则可以将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