r: операция цикла for с вложенными индексами выполняется очень медленно

У меня есть операция, которую я хотел бы выполнить для каждой строки фрейма данных, изменяя один столбец. Я сторонник apply/ddply/sqldf, но я использую циклы, когда они имеют смысл, и я думаю, что это один из тех случаев. Этот случай сложен тем, что изменяемый столбец зависит от информации, которая изменяется по строкам; в зависимости от информации в одной ячейке, я должен внести изменения только в одну из десяти других ячеек в этой строке. При 75 столбцах и 20000 строках операция занимает 10 минут, в то время как все остальные операции в моем сценарии занимают 0-5 секунд, максимум десять секунд. Я свел свою проблему к очень простому тестовому примеру, приведенному ниже.

n <- 20000
t.df <- data.frame(matrix(1:5000, ncol=10, nrow=n) )
system.time(
 for (i in 1:nrow(t.df)) {
 t.df[i,(t.df[i,1]%%10 + 1)] <- 99
 }
)

Это занимает 70 секунд при десяти столбцах и 360 при ncol=50. Это безумие. Являются ли циклы неправильным подходом? Есть ли лучший, более эффективный способ сделать это?

Я уже пробовал инициализировать вложенный терм (t.df[i,1]%%10 + 1) как список вне цикла for. Это экономит около 30 секунд (из 10 минут), но усложняет приведенный выше код примера. Так что это помогает, но не является решением.

Моя текущая лучшая идея пришла во время подготовки этого тестового примера. Для меня только 10 столбцов имеют значение (а 75-11 столбцов не имеют значения). Поскольку время выполнения так сильно зависит от количества столбцов, я могу просто выполнить описанную выше операцию на кадре данных, исключающем нерелевантные столбцы. Это позволит мне сократить время до чуть более минуты. Но является ли "цикл for с вложенными индексами" лучшим способом решения моей проблемы?

15
задан enfascination 30 November 2011 в 18:48
поделиться