r使用未知列数将数据从长改宽

r使用未知列数将数据从长改宽,r,reshape,R,Reshape,我相信这是微不足道的,但我找不到怎么做 我有一个数据框架,其中有个人,每个人都可以有几个属性,每个属性以多种方式分类。现在它的形状很长,记录看起来像(在示意图中,实际上它有点复杂): 我想要的是每个ID对应一行,每个ID对应一对列,然后对应原始文件中每个属性和PropClass对应一对列,因此在本例中: IndividualID Prop1 PropClass1 Prop2 PropClass2 Prop3 PropClass3 1 X 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
因此,必须有与原始数据集中任何individualID的最大行数一样多的Prop和PropClass变量(不是很大,大约5行),如果一个人在原始数据集中的行数少于最大行数,那么对该个人来说没有任何意义的额外列中就有NAs。个人的Prop和PropClass变量的顺序并不重要(尽管它也可能是长格式文件的原始顺序)


显然,如果每个可能的Prop值都有一对Prop和propClass列,那么很容易做到这一点(例如,使用重塑),但是有几百个可能的Prop值,因此文件变得巨大而无用。我不敢相信没有一个简单的方法来做我想做的事情,但我还没有找到它,尽管在我看来,这是一个刻苦的搜索。请告诉我我是个白痴,如果是的话,我该如何治疗我的白痴。

也许有更有效的方法,但我现在想不起来。由于有两个变量需要转换为宽格式,我认为您可能需要分别转换它们,然后将它们合并在一起。不过我很想被证明是错的。为此,我创建了两个新变量,为每个新ID生成一个列序列。这将使它们能够轻松地用NAs填充。有了新的列,很容易将它们转换成正确的格式并合并在一起

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
库(plyr)
图书馆(E2)
#假设数据被读入名为x的变量

这样的事情可以接受吗

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")

test.dt这基本上就是我概述的,只是在一组不同的步骤中…很高兴看到我们或多或少在同一页上。嗨@Chase。我想我们实际上是同时提交的!!我觉得你的答案更干净、更漂亮。是的,谢谢,我很确定这对我也适用,但我选择了@Chase的版本,因为它有点干净。谢谢,这很有效(并且很容易扩展到我真正遇到的稍微复杂的情况)。
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")