Обновить переменную в цикле в R - PullRequest
0 голосов
/ 26 ноября 2011

Как мне изменить мой код для обновления переменных внутри цикла?

В частности, я хочу сделать что-то вроде следующего:

myMatrix1 <- read.table(someFile)
myMatrix2 <- read.table(someFile2)

for (i in nrow(myMatrix2))
{       
    myMatrix3 <- myMatrix1[which(doSomeTest),]
    myMatrix4 <- rep(myMatrix2$header1,nrow(myMatrix1)) 
    myMatrix5 <- rep(myMatrix2$header2, nrow(myMatrix1))        
    myMatrix6 <- cbind(myMatrix3, myMatrix4, myMatrix5) 
    # *see question

}

Как я могу получить myMatrix6 для обновлениявместо переназначенного произведения cbind(myMatrix3, myMatrix4, myMatrix5)?Другими словами, если первая итерация (i = 1) дала myMatrix6:

> 1   1    1   1
> 2   2    2   2

, а вторая итерация (i = 2) дала myMatrix 6:

> 3   3    3   3
> 4   4    4   4

как получить фрейм данных (?):

> 1   1    1   1
> 2   2    2   2
> 3   3    3   3
> 4   4    4   4

ОБНОВЛЕНИЕ:

У меня - благодаря предложениям DWin и Тимо - получено следующее.Однако следующий код занял у меня около 2 часов, чтобы запустить мои наборы данных.Есть ли способы заставить его работать быстрее ???(без использования более мощного компьютера я могу добавить)

# create empty matrix for sedimentation
myMatrix6 <- data.frame(NA,NA,NA,NA)[0,]
names(myMatrix6) <- letters[1:4]

# create empty matrix for bore
myMatrix7 <- data.frame(NA,NA,NA,NA)[0,]
names(myMatrix7) <- letters[1:4]

for (i in 1:nrow(myMatrix2))
{       
    # create matrix that has the value of myMatrix1$begin being 
    # situated between the values of myMatrix2begin[i] and myMatrix2finish[i]
    myMatrix3 <- myMatrix1[which((myMatrix1$begin > myMatrix2$begin[i]) & (myMatrix1$begin < myMatrix2$finish[i])),]

    myMatrix4 <- rep(myMatrix2$sedimentation, nrow(myMatrix3))

    if (is.na(myMatrix2$boreWidth[i])) {
        myMatrix5 <- rep(NA, nrow(myMatrix3))
    }
    else if (myMatrix2$boreWidth[i] == 0) {
        myMatrix5 <- rep(TRUE, nrow(myMatrix3))
    }
    else if (myMatrix2$boreWidth[i] > 0) {
        myMatrix5 <- rep(FALSE, nrow(myMatrix3))
    }

    myMatrix6 <- rbind(myMatrix6, cbind(myMatrix3, myMatrix4))
    myMatrix7 <- rbind(myMatrix7, cbind(myMatrix3, myMatrix5))
}

Ответы [ 2 ]

2 голосов
/ 26 ноября 2011

Вместо этого вы инициализируете myMatrix6 пустым data.frame и повторно привязываете результаты (что может быть неэффективно).Если важна эффективность, вы должны предварительно выделить нужный размер и заполнить строки в data.frame индексированием.

# Method # 1 code
myMatrix6 <- data.frame(NA,NA,NA,NA)[0,]
names(myMatrix6) <- letters[1:4]

for (i in nrow(myMatrix2)) {       
    myMatrix3 <- myMatrix1[which(doSomeTest),]
    myMatrix4 <- rep(myMatrix2$header1,nrow(myMatrix1)) 
    myMatrix5 <- rep(myMatrix2$header2, nrow(myMatrix1))        
    myMatrix6 <- rbind( myMatrix6, cbind(myMatrix3, myMatrix4, myMatrix5) )
                           }
1 голос
/ 26 ноября 2011

В вашем коде вы имеете дело не с матрицами (в смысле R), а с фреймами данных, так как read.table возвращает фрейм данных.

В любом случае вы можете добавить один кадр / матрицу данных в другой (при условии совпадения имен столбцов) с помощью команды rbind

Например, если

> a = data.frame(x=c(1,2,3),y=c(4,5,6),z=c(7,8,9))
> b = data.frame(x=c(4,5),y=c(5,6),z=c(6,7))

1010 * тогда *

> rbind(a,b)
  x y z
1 1 4 7
2 2 5 8
3 3 6 9
4 4 5 6
5 5 6 7

В коде, который вы предоставляете, есть и другие ошибки. Например

for (i in length(someVector)))

должно быть

for (i in 1:length(someVector)))

R имеет много функций для итерации по data.frames, векторам и т. Д. И может выполнять любые преобразования данных. Большую часть времени не нужно писать цикл for.

Если вы предоставите более подробную информацию о том, что вы пытаетесь сделать, возможно, мы сможем найти более простое решение.

EDIT:

Из вашего пост-обновления видно, что вы пытаетесь выполнить какое-то преобразование между «широким» и «длинным» форматом и отфильтровать некоторые строки, которые не прошли тест. Поправь меня, если я ошибаюсь.

В любом случае, если это так, вам следует проверить команду reshape. Кроме того, существует пакет reshape, содержащий чрезвычайно полезные команды melt и cast, которые могут выполнять такие преобразования довольно эффективно. Также есть команда merge для выполнения определенных операций «соединения» для фреймов данных. Я вполне уверен, что ваша проблема может быть решена с помощью комбинации приведенных выше команд, но это зависит от точных деталей.

Для фильтрации строк / столбцов по некоторым критериям проверьте команду subset.

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