запись в фрейм данных из цикла for в R - PullRequest
15 голосов
/ 02 апреля 2010

Я пытаюсь записать цикл во фрейм данных в R, например, такой цикл>

for (i in 1:20) {
print(c(i+i,i*i,i/1))}

и записать каждую строку из 3 значений во фрейм данных с тремя столбцами, чтобы каждая итерация брала новую строку. Я попытался использовать матрицу с ncol = 3 и заполнить строками, но только получить последний элемент из цикла.

Спасибо.

Ответы [ 4 ]

23 голосов
/ 02 апреля 2010

Вы можете использовать rbind:

d <- data.frame()
for (i in 1:20) {d <- rbind(d,c(i+i, i*i, i/1))}
10 голосов
/ 29 июня 2012

Другой способ будет

do.call("rbind", sapply(1:20, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE))


     [,1] [,2] [,3]
 [1,]    2    1    1
 [2,]    4    4    2
 [3,]    6    9    3
 [4,]    8   16    4
 [5,]   10   25    5
 [6,]   12   36    6

Если вы не укажете simplify = FALSE, вы должны транспонировать результат, используя t. Это может быть утомительно для больших конструкций.

Это решение особенно удобно, если у вас есть набор данных на большой стороне и / или вам нужно повторять это много раз.

Я предлагаю некоторые варианты решений в этой «теме».

> system.time(do.call("rbind", sapply(1:20000, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE)))
   user  system elapsed 
   0.05    0.00    0.05 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1)))
   user  system elapsed 
   0.14    0.00    0.14 

> system.time({d <- matrix(nrow=20000, ncol=3) 
+ for (i in 1:20000) { d[i,] <- c(i+i, i*i, i/1)}})
   user  system elapsed 
   0.10    0.00    0.09 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1)))
   user  system elapsed 
  62.88    0.00   62.99 
6 голосов
/ 29 июня 2012

Если все ваши значения имеют одинаковый тип и вы знаете количество строк, вы можете использовать матрицу следующим образом (это будет очень быстро):

d <- matrix(nrow=20, ncol=3) 
for (i in 1:20) { d[i,] <- c(i+i, i*i, i/1)}

Если вам нужен фрейм данных, вы можете использовать rbind (как предлагает другой ответ), или функции из пакета plyr, такие как:

library(plyr)
ldply(1:20, function(i)c(i+i, i*i, i/1))
5 голосов
/ 02 апреля 2010
У циклов

For есть побочные эффекты, поэтому обычный способ сделать это - создать пустой кадр данных перед циклом, а затем добавлять к нему на каждой итерации. Вы можете создать экземпляр с правильным размером, а затем присвоить свои значения строке i на каждой итерации, или добавить к ней и переназначить все, используя rbind().

Первый подход будет иметь лучшую производительность для больших наборов данных.

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