R:将多个列合并为一个列,每行有一个值

时间:2016-08-25 02:58:11

标签: r dataframe merge

现在我有一个这样的数据框:

   Z    A  B  C  D  F
1  82   1 NA NA NA 77
2 454  NA  2 NA NA 18
3 606  NA NA  3 NA 12
4  55  NA NA NA  4 23
5  32  NA  2 NA NA  4
# And many more rows follows

每列中只有一列A,B,C,D具有值,并且每列中的值相同。我想将它们合并为一个单独的列,1,2,3,4将成为这个新列的因子级别。

期望的结果:

   Z    A  B  C  D  F  E
1  82   1 NA NA NA 77  1
2 454  NA  2 NA NA 18  2
3 606  NA NA  3 NA 12  3
4  55  NA NA NA  4 23  4
5  32  NA  2 NA NA  4  2
# And many more rows follows
# Dropping A,B,C,D as a side-effect is OK

我尝试使用ifelse语句(data$E = ifelse(data$A == 1, 5, data$A),但每个ifelse语句都会覆盖之前的修改,因此最后只有4级写入E列。

我可以合并这些列吗?滴A,B,C,D作为副作用是可以的。谢谢!

编辑:如果左边和右边有更多列无关紧要怎么办?需要某种切片吗? (参见编辑的代码)

2 个答案:

答案 0 :(得分:2)

只要每行只有一个值,rowSums就可以了:

df$E <- rowSums(df, na.rm = TRUE)

df
##    A  B  C  D E
## 1  1 NA NA NA 1
## 2 NA  2 NA NA 2
## 3 NA NA  3 NA 3
## 4 NA NA NA  4 4
## 5 NA  2 NA NA 2

答案 1 :(得分:-3)

我们可以将pmaxpminna.rm = TRUE

一起使用
df1$E <- do.call(pmax, c(df1, na.rm=TRUE))
df1
#   A  B  C  D E
#1  1 NA NA NA 1
#2 NA  2 NA NA 2
#3 NA NA  3 NA 3
#4 NA NA NA  4 4
#5 NA  2 NA NA 2

我们也可以使用max.col(在此示例中,我们不需要cbind行索引)

max.col(!is.na(df1))
#[1] 1 2 3 4 2

一般

df1[cbind(1:nrow(df1), max.col(!is.na(df1)))]

或者我们可以使用%*%来获取每行非NA元素的列索引

(+(!is.na(df1)) %*% seq_along(df1))[,1]

如果我们使用hadleyversecoalesce也可以提供帮助

library(dplyr)
df1 %>% 
     mutate(E = coalesce(A, B, C, D))
#   A  B  C  D E
#1  1 NA NA NA 1
#2 NA  2 NA NA 2
#3 NA NA  3 NA 3
#4 NA NA NA  4 4
#5 NA  2 NA NA 2

data.table

的其他选项
library(data.table)
setDT(df1)[, E := na.omit(unlist(.SD)) ,1:nrow(df1)]

注意:此解决方案基于OP的初始示例/预期输出以及此帖子的title R:将多个列合并为一个,每行一个值< /强>

数据

df1 <- structure(list(A = c(1L, NA, NA, NA, NA), B = c(NA, 2L, NA, NA, 
2L), C = c(NA, NA, 3L, NA, NA), D = c(NA, NA, NA, 4L, NA)), .Names = c("A", 
"B", "C", "D"), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5"))