将值从数据帧转发到另一个数据帧。应用? sapply?

时间:2011-08-29 17:36:36

标签: r dataframe

我有以下数据框

data<-data.frame(ID=c("a", "b", "c", "d"), zeros=c(3,2,5,4), ones=c(1,1,2,1))


   ID zeros ones
1  a     3    1
2  b     2    1
3  c     5    2
4  d     4    1

我希望创建另一个包含2列的数据框:

第一列(id)重复ID(零+一)次 第二列值应为c(rep(0,零),rep(1,ones))

这样结果就是

    id value
1   a  0
2   a  0
3   a  0
4   a  1
5   b  0
6   b  0
7   b  1
8   c  0
9   c  0
10  c  0
11  c  0
12  c  0
13  c  1
14  c  1
15  d  0
16  d  0
17  d  0
18  d  0
19  d  1

我试过了data.frame(id=(rep(data$ID, (data$zeros+data$ones))), value=c(rep(0, data$zeros), rep(1, data$ones)))但是没有用。有任何想法吗?提前谢谢

4 个答案:

答案 0 :(得分:4)

使用ddply包中的plyr可能有点过分,但这是我第一件事:

ddply(dat,.(ID),function(x){data.frame(value = rep(c(0,1),times = c(x$zeros,x$ones)))})

哦,我将数据框的名称更改为dat以避免坏习惯(data是常用函数的名称)。

答案 1 :(得分:1)

由于您已经为第一列提供了基础R解决方案,因此这是第二列的解决方案:

lengths<-as.vector(t(as.matrix(data[,2:3]))) #notice the t
what<-rep(c(0,1), nrow(data))
times<-rep(what, lengths)

修改:更改了上面的小问题并对其进行了测试。它现在有效。

答案 2 :(得分:1)

这是一个基础R解决方案。我更喜欢plyr我自己的过度杀伤力:

dat <- data.frame(ID = letters[1:4], zeros = c(3,2,5,4), ones = c(1,1,2,1))

do.call("rbind"
    , apply(dat, 1, function(x) 
        data.frame(cbind(id = x[1], value = rep(0:1, times = x[2:3])))
    )
)

答案 3 :(得分:0)

我也更喜欢plyr方法,但我想我会抛出另一个与重新整形数据相关的基本R解决方案,然后再复制它。 (也使用dat代替data):

names(dat)[2:3] <- c("times.0", "times.1")
tmp <- reshape(dat, varying=2:3, direction="long")
tmp <- tmp[rep(seq(length=nrow(tmp)),tmp$times),c("ID","time")]
names(tmp) <- c("id","value")
tmp <- tmp[order(tmp$id, tmp$value),]
rownames(tmp) <- NULL

不像其他一些基础解决方案那样优雅,因为它需要中间存储,但可能很有趣。