如何在R中重塑这些数据?

时间:2012-03-06 21:52:15

标签: r reshape

所以 - 我正在使用一个df,这个重复观察组由一个id索引,如下所示:

id | x1 | x2 | y1 | y2
1    a    b    c    2
1    a    b    d    3
1    a    b    e    4
2    ...
2    ...
...

,即每个组中的所有变量都是相同的,除了y1和y2(一般来说,y2'修改'y1。)我在这里列出的所有这些变量都是因子。我想做的是将这些组中的每一组变成类似于以下内容的东西:

id | x1 | x2 | y1' | y2' | y3' 
1    a    b    c-2   d-3   e-4
2    ...

其中y1(y1-prime)是y1和y2的相邻值的连接,其间有一个破折号。但是,y1的数量不同于id-group到id-group,但我很满意一个非常宽的数据框架,允许这些附加功能作为解决方案。无论如何,我(相当徒劳地,我必须承认)尝试使用reshape2融化和转换这些数据,但在这一点上,我不确定我是不是正确地做这个,或者那个包不是一个适合我在这里尝试做的事情。任何建议将不胜感激 - 谢谢!

3 个答案:

答案 0 :(得分:1)

如果我正确理解了这个问题,可以使用plyr

来实现
foo <- read.table(textConnection("id  x1  x2  y1  y2
1    a    b    c    2
1    a    b    d    3
1    a    b    e    4"),header=TRUE)


library("plyr")

ddply(foo,.(x1,x2),with,{
        res <- data.frame(
          id = id[1],
          x1 = x1[1],
          x2 = x2[1])
        for (i in 1:length(y1))
        {
          res[[paste("y",i,sep="")]] <- paste(y1,y2,sep="-")[i]
        }
        return(res)
      }
    )

返回:

  id x1 x2  y1  y2  y3
1  1  a  b c-2 d-3 e-4

答案 1 :(得分:1)

我看到了Sacha的回答,并认为我会尝试将其扩展到更长的数据集。我认为这不会给你你想要的结果,但我不确定。我并不完全清楚你要做什么。所以这是我尝试做你想做的事,但我不完全确定那是什么:

foo <- read.table(textConnection("id  x1  x2  y1  y2
1    a    b    c    2
1    a    b    d    3
1    a    b    e    4
2    a    b    f    2
2    a    b    g    3
2    a    b    h    4"),header=TRUE)


new <- transform(foo, time.var=paste(id, x1, x2, sep=""), 
    y1=paste(y1, y2, sep="-"))[, -5] 

new <- data.frame(unique(foo[, 1:3]), t(unstack(new[, 4:5])))
names(new)[4:6] <- paste("y", 1:3, sep="")
new

虽然我认为如果你把id放入x1和x2(我猜这可能更具普遍性),sacha的答案和我的答案一样:

ddply(foo,.(id, x1,x2),with,{
        res <- data.frame(
          id = id[1],
          x1 = x1[1],
          x2 = x2[1])
        for (i in 1:length(y1))
        {
          res[[paste("y",i,sep="")]] <- paste(y1,y2,sep="-")[i]
        }
        return(res)
      }
    )

编辑:此解决方案可能更具概括性:

new <- transform(foo, y=paste(y1, y2, sep="-"), stringsAsFactors=FALSE)
aggregate(y~id+x1+x2, new, c)

答案 2 :(得分:0)

是的,这就是reshape包的用途。首先准备你的数据:

foo <- transform(foo,
                 y = paste(y1,y2, sep = "-"),
                 ix = unlist(tapply(id, id, function(gr) 1:length(gr))))

然后继续进行转换:

mfoo <- melt(foo, measure.vars = "y")
cast(mfoo, id + x1 + x2 ~ variable + ix)

应该给予

  id x1 x2 y_1 y_2  y_3
1  1  a  b c-2 d-3  e-4
2  2  a  b f-2 h-4 <NA>

使用数据集

foo <- read.table(textConnection("id  x1  x2  y1  y2
1    a    b    c    2
1    a    b    d    3
1    a    b    e    4
2    a    b    f    2
2    a    b    g    3"),header=TRUE)

[编辑:重新整形,使用reshape2,您应该使用dcast代替cast]