У меня есть операция, которую я хотел бы запустить для каждой строки фрейма данных, меняя один столбец. Я человек 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 столбцов не имеют значения). Поскольку время выполнения в значительной степени зависит от количества столбцов, я могу просто выполнить вышеуказанную операцию для фрейма данных, который исключает ненужные столбцы. Это доведет меня до чуть более минуты. Но является ли «цикл с вложенными индексами» лучшим способом решения моей проблемы?