如何在 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)
我有以下数据框:
原文:
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)