R:快速乘以data.frame(或其他数据结构)中的选定行

时间:2011-01-22 12:03:52

标签: r dataframe

我有一个像data.frame这样的类型的对象,但更大:

> head(mydf)  
   id1     id2   n  
1    0 1032142   3  
2    0 1072163   1  
3    0  119323   2  

我需要打印到文件列a1a1,每个列n次。所以我可以得到这样的文件:

0 1032142  
0 1032142  
0 1032142  
0 1072163  
0  119323  
0  119323  

我尝试了以下解决方案,但是它们使用了明确的for循环并且非常慢(使用我的数据完成它们需要几天时间):

for (j in 1:(nrow(mydf))) for (i in 1:(mydf[j,"n"])) write.table( mydf[j,c("id1","id2")], file="trials", append=T, row.names= F, col.names=F )

另一个尝试使用相乘的行构建一个新的data.frame,但运行速度更慢。

towrite=data.frame(); for (j in 1:(nrow(mydf))) for (i in 1:(mydf[j,"n"])) towrite=rbind(towrite,mydf[j,c("id1","id2")])

在R下解决这个问题的最简单,最快捷的方法是什么?

3 个答案:

答案 0 :(得分:6)

尝试对数据进行子集化并一次保存:

mydf[rep(1:nrow(mydf), mydf$n), ]

如果您的数据是数字,那么操纵矩阵要快得多:

mymat <- as.matrix(mydf)
reps <- as.integer(mydf$n)
mymat[rep(1:nrow(mymat), reps), ]

  id1     id2 n
1   0 1032142 3
1   0 1032142 3
1   0 1032142 3
2   0 1072163 1
3   0  119323 2
3   0  119323 2

如果您设法操纵原始data.frame,那么您可能能够处理上述矩阵。

答案 1 :(得分:1)

如果您只想将每行 n 次写入文件,请尝试:

加载演示数据:

data <- structure(list(id1 = c(0L, 0L, 0L), 
    id2 = c(1032142L, 1072163L, 119323L), 
    n = c(3L, 1L, 2L)), .Names = c("id1", "id2", "n"), class = "data.frame", row.names = c(NA, -3L))

将所有行 n 次写入“output.txt”:

file = 'output.txt'
write.table(data[0,], file=file, row.names=FALSE)
apply(data, 1, function(x) replicate(x[3], write.table(t(x[1:2]), file=file, append=TRUE, col.names=FALSE, row.names=FALSE)))

我相信这可以写得更好:)

答案 2 :(得分:0)

也许你可以尝试申请和下沉。我不确定apply是否实际上比for循环更快(tapply和lapply definatly)。

mydat=data.frame(id1=0,id2=rnorm(5),n=sample(1:10,5))

mydat

sink("test.txt")
apply(mydat,1,function(x)cat(paste(rep(paste(x[1:2],collapse="\t"),x[3]),"\n" )))
sink()

我知道代码看起来很糟糕