如何根据列值将多列合并为一列?

时间:2018-02-17 09:33:17

标签: r

我想使用值将一些列聚合为一个。

我有一个像这样的矩阵:

| X  | Y1 | Y2 | Y3 | Y4 |
|----|----|----|----|----|
|id1 | 0  | 0  | 1  | 0  |
|id2 | 0  | 1  | 0  | 0  |
|id3 | 0  | 1  | 0  | 0  |
|id4 | 0  | 0  | 0  | 1  |
|id5 | 0  | 1  | 0  | 0  |
|id6 | 1  | 0  | 0  | 0  |

我想要检索这样的矩阵:

| X  | Y  |
|----|----|
|id1 | Y3 |
|id2 | Y2 |
|id3 | Y2 |
|id4 | Y4 |
|id5 | Y2 |
|id6 | Y1 |

我不知道我怎么做到这一点。

感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

这是一个使用基础R的max.col的矢量化方法,

names(df)[max.col(df[-1])+1]
#[1] "Y3" "Y2" "Y2" "Y4" "Y2" "Y1"

要构建输出,只需使用data.frame

即可
data.frame(X = df$X, Y = names(df)[max.col(df[-1])+1])

给出,

    X  Y
1 id1 Y3
2 id2 Y2
3 id3 Y2
4 id4 Y4
5 id5 Y2
6 id6 Y1

max.col的更简化版本,因为它也适用于逻辑语句,可以是(@Jaap的赞美)

names(df)[max.col(df == 1)]

答案 1 :(得分:3)

tidyrdplyr的一种方式:

library(dplyr)
library(tidyr)

df %>% 
  gather(key, value, -X) %>% 
  filter(value == 1) %>% 
  arrange(X)

返回:

# A tibble: 6 x 3
  X     key   value
  <chr> <chr> <chr>
1 id1   Y3    1    
2 id2   Y2    1    
3 id3   Y2    1    
4 id4   Y4    1    
5 id5   Y2    1    
6 id6   Y1    1   

数据:

df <- data.frame(stringsAsFactors=FALSE,
                 X = c( "id1", "id2", "id3", "id4", "id5", "id6"),
                 Y1 = c( "0", "0", "0", "0", "0", "1"),
                 Y2 = c("0", "1", "1", "0", "1", "0"),
                 Y3 = c("1", "0", "0", "0", "0", "0"),
                 Y4 = c("0", "0", "0", "1", "0", "0"))

答案 2 :(得分:2)

这是base R解决方案。我使用以下data.frame作为插图

df <- data.frame(X = c("id1", "id2", "id3", "id4"),
                 Y1 = c(1, 0, 0, 0),
                 Y2 = c(0, 1, 0, 1),
                 Y3 = c(0, 0, 1, 0))
df
#    X Y1 Y2 Y3
#1 id1  1  0  0
#2 id2  0  1  0
#3 id3  0  0  1
#4 id4  0  1  0

在第一步中,对于每一行,我将查找包含值1的列的位置。

col_positions <- sapply(X = 1:nrow(df), FUN = function(x) which(df[x, ] == 1))
col_positions
#[1] 2 3 4 3

现在,您可以使用此向量过滤colnames(df)并将结果附加到数据中。

df$Y <- colnames(df)[col_positions]
df
#    X Y1 Y2 Y3  Y
#1 id1  1  0  0 Y1
#2 id2  0  1  0 Y2
#3 id3  0  0  1 Y3
#4 id4  0  1  0 Y2

如果您只想保留列XY,可以选择它们,例如如下

df[, colnames(df) %in% c("X", "Y")]
相关问题