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