我有以下数据框
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)))
但是没有用。有任何想法吗?提前谢谢
答案 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
不像其他一些基础解决方案那样优雅,因为它需要中间存储,但可能很有趣。