我有以下数据框:
id,property1,property2,property3
1,1,0,0
2,1,1,0
3,0,0,1
4,1,1,1
d.f <- structure(list(id = 1:4, property1 = c(1L, 1L, 0L, 1L), property2 = c(0L,
1L, 0L, 1L), property3 = c(0L, 0L, 1L, 1L)), .Names = c("id",
"property1", "property2", "property3"), class = "data.frame", row.names = c(NA,
-4L))
获取以下数据框的最简单方法是什么:
id,properties_list
1,property1
2,property1, property2
3,property3
4,property1, property2, property3
也许像melt
或reshape
这样的花哨选项?
答案 0 :(得分:2)
这真的不是重塑。使用paste
。
for(i in seq(1,3) ) {
tf <- as.logical(d.f[,i+1])
d.f[,i+1] <- as.character(d.f[,i+1])
d.f[,i+1][tf] <- colnames(d.f)[i+1]
d.f[,i+1][!tf] <- " "
}
d.f$property.list <- paste(d.f[,2],d.f[,3],d.f[,4],sep=" ")
与往常一样,如果您首先dput()
数据框,您将获得更好的答案:
d.f <- structure(list(id = 1:4, property1 = c(1L, 1L, 0L, 1L), property2 = c(0L,
1L, 0L, 1L), property3 = c(0L, 0L, 1L, 1L)), .Names = c("id",
"property1", "property2", "property3"), class = "data.frame", row.names = c(NA,
-4L))
答案 1 :(得分:2)
实际上这不是一个合适的数据帧,必须具有相同数量的条目的所有行,所以正确的答案是你可能想要一个列表。如果那不是你想要的,那就试试这个:
dfrm[-1] <- t( apply(dfrm[-1], 1, function(x) ifelse(x, names(x), "") ) )
dfrm
id property1 property2 property3
1 1 property1
2 2 property1 property2
3 3 property3
4 4 property1 property2 property3
您需要t()因为应用行操作会转换其结果,因为R强加了列主要顺序。
如果您确实需要列表版本,那么这里有一种方法:
prop_list <- apply(dfrm[-1], 1, function(x) c(names(x)[ as.logical(x)] ) )
names(prop_list) <- dfrm[,1]
prop_list
$`1`
[1] "property1"
$`2`
[1] "property1" "property2"
$`3`
[1] "property3"
$`4`
[1] "property1" "property2" "property3"
答案 2 :(得分:2)
此解决方案假设您正在寻找类似于gsk3如何解释问题(将属性粘贴在一起)的数据框,但必须避免使用for
循环,这只是因为我们如何使用R滚动:
property_list <- apply(d.f[,-1],1,
FUN=function(x,nms){paste(nms[as.logical(x)],collapse=",")},
nms=colnames(d.f)[-1])
as.data.frame(cbind(d.f$id,property_list))
V1 property_list
1 1 property1
2 2 property1,property2
3 3 property3
4 4 property1,property2,property3