R: Быстрое умножение выбранных строк в data.frame (или другой структуре данных) - PullRequest
4 голосов
/ 22 января 2011

У меня есть объект типа data.frame, но гораздо больше:

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

Мне нужно напечатать в файл столбцы a1 и a1, каждый из них 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 ]

6 голосов
/ 22 января 2011

Попробуйте установить подмножество своих данных и сохранить в одной партии:

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 голос
/ 22 января 2011

Если вы хотите записать каждую строку 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)))

Я уверен, что это можно было бы написать намного лучше :)

0 голосов
/ 22 января 2011

Может быть, вы можете попробовать применить и утонуть.Я не уверен, что применение на самом деле быстрее, чем for-loop, хотя (определенно и непринужденно).

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

Я знаю, что код выглядит ужасно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...