如何在 R 中重塑以下数据框

How to reshape the following dataframe in R

我有以下数据框:

原文:

ID  C1  C2  C3  C4  C5  C6  C7  C8
A11 0   1   0   0   0   0   1   0
A21 0   0   1   1   0   0   0   0
A31 0   0   0   0   1   0   1   0
A41 0   0   0   0   0   1   0   0
A51 0   0   0   0   0   1   0   0
A61 0   0   0   0   0   1   0   1
A71 0   0   1   1   0   0   0   0
A81 1   0   0   1   0   0   1   0
A91 0   1   0   1   0   0   0   1
A10 1   0   1   0   0   1   0   1

我最终希望数据采用以下格式:

决赛:

A11 C2  C7

A21 C3  C4

A31 C5  C7  

A41 C6  

A51 C6

A61 C6  C8  

A71 C3  C4

A81 C1  C4  C7

A91 C2  C4  C8

A10 C1  C3  C6  C8

因此,基本上,无论值 != 0 在哪里,都用该列中的变量名称替换该值。有没有办法在 R 中执行上述操作?

谢谢!

这是一个使用 apply 的方法,它 return 是一个列表,其中列表项名称是行名称:

# construct reproducible example
set.seed(1234)
df <- data.frame(apple=sample(c(0,1), 10, replace=T), 
                 banana=sample(c(0,1), 10, replace=T),
                 carrot=sample(c(0,1), 10, replace=T))
# give it some row names
rownames(df) <- letters[1:10]

# return the list
myList <- apply(df, 1, function(i) names(df)[i!=0])

使用此方法时,您需要确保数据有足够的变化。这是因为 apply(许多 R 函数也是如此)试图简化输出的数据类型。 @digemall 提供的例子,

df <- structure(list(ID = c("A11", "A21", "A31", "A41", "A51", "A61" ), 
                     C1 = c(1, 1, 1, 1, 1, 1), C2 = c(0, 0, 0, 0, 0, 0)),
                .Names = c("ID", "C1", "C2"), row.names = c(NA, 6L), class = "data.frame")

return是一个矩阵,有用之处在于它提供了所需的信息,但不是预期的列表类型对象。下面是一个更阴险的例子:

df <- data.frame(apple=c(0,1), banana=c(1,0))

其中该方法将 return 一个无用的字符向量。

@digemall 建议的一种更安全的方法是使用 lapply 向下循环行。因为 lapply 总是 return 是一个列表,所以我们不必担心之前的任何一个问题:

myList <- lapply(1:nrow(df),function(i)names(df)[df[i,]==1])

现在我们必须加回名字:

names(res) <- row.names(df)