我确信这是微不足道的,但我找不到怎么做。
我有一个数据框,其中有个人,每个人都可以拥有多个属性,每个属性都以多种方式分类。 Currenly它的形状很长,看起来很像(在示意图中,实际上它有点复杂):
IndividualID Property PropClass
1 X A
1 Y B
2 X A
3 Y B
3 W C
3 Z A
我想要的是每个个人ID的一行,包含个人ID,然后是每个属性的列对,以及该个人在原始文件上拥有的PropClass,所以在这种情况下:
IndividualID Prop1 PropClass1 Prop2 PropClass2 Prop3 PropClass3
1 X A Y B NA NA
2 X A NA NA NA NA
3 Y B W C Z A
因此,必须有与原始数据集中任何个别ID的最大行数(不大,约为5)一样多的Prop和PropClass变量,并且个人在原始数据集中的行数少于最大数量,对于那个人来说没有任何意义的额外列在其中有NA。个人的Prop和PropClass变量的顺序无关紧要(尽管它也可能是长格式文件的原始顺序)。
显然,如果你为Prop的每个可能值都有一对Prop和propClass列,那么很容易做到这一点(例如使用reshape),但是Prop有几百个可能的值,所以文件变得庞大且无用。我无法相信没有一种简单的方法可以做我想要的事情,但我还是没有找到它,尽管在我看来,这是一种刻薄的搜索。请告诉我,我是个白痴,如果是的话,我怎么能治好我的愚蠢。
答案 0 :(得分:2)
这可能是一种更有效的方法,但我现在想不到它。由于需要将两个变量转换为宽格式,我认为您可能需要单独转换它们然后将两者合并在一起。我很想被证明是错的。为此,我创建了两个新变量,为每个新ID生成一个列序列。这将使他们能够轻松填充NA。使用新列,可以很容易地将它们转换为正确的格式并将它们合并在一起。
library(plyr)
library(reshape2)
#Assumes your data is read into a variable named x
x <- ddply(x, "IndividualID", transform,
castPropClass = paste0("PropClass", seq(length(PropClass))),
castProp = paste0("Prop", seq(length(Property))))
#Use these two new variables to cast into wide format. Wrap in merge to join together:
merge(dcast(IndividualID ~ castPropClass, value.var = "PropClass", data = x),
dcast(IndividualID ~ castProp, value.var = "Property", data = x))
#Gives you this:
IndividualID PropClass1 PropClass2 PropClass3 Prop1 Prop2 Prop3
1 1 A B <NA> X Y <NA>
2 2 A <NA> <NA> X <NA> <NA>
3 3 B C A Y W Z
这显然没有列的正确“顺序”,但数据本身是正确的。
答案 1 :(得分:1)
这样的事情会被接受吗?
test.dt<-data.frame(id=(c(1,1,2,3,3,3)), property=(c("X","Y","X","Y","W","Z")), property.clss=(c("A","B","A","B","C","A")))
library(reshape)
m<-melt(data=test.dt, id.vars="id", measure.vars=c("property.clss"))
m
n<-melt(data=test.dt, id.vars="id", measure.vars=c("property"))
n
c1<-data.frame(cast(m, id~value))
colnames(c1)<-c("id", paste("property",colnames(c1)[colnames(c1)!="id"],sep=""))
c1
c2<-data.frame(cast(n,id~value))
colnames(c2)<-c("id", paste("property.clss",(colnames(c2)[colnames(c2)!="id"]),sep=""))
c2
merge(c1,c2,by="id")