[英]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
的方法,该方法返回一个列表,其中列表项名称为行名称:
# 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")
返回一个矩阵,该矩阵很有用,因为它提供了所需的信息,但不是预期的列表类型对象。 更加阴险的例子如下:
df <- data.frame(apple=c(0,1), banana=c(1,0))
该方法将返回无用的字符向量。
@digemall建议的一种更安全的方法是使用lapply
遍历行。 因为lapply
总是返回一个列表,所以我们不必担心前面的两个问题:
myList <- lapply(1:nrow(df),function(i)names(df)[df[i,]==1])
现在我们必须添加名称:
names(res) <- row.names(df)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.