Я пытаюсь написать функцию, которая заменяет отсутствующие значения выбранных переменных во фрейме данных их запаздывающими значениями (я использую задержку на одно наблюдение) в R. Я успешно написал для этого следующий цикл for:
testdata <- data.frame(x1 = c(1:10),
x2 = c(4, 3, NA, 7, 8, NA, 9, NA, 10, 11),
x3 = c(4, 3, NA, 7, 8, NA, 9, NA, NA, 11),
x4 = c("a", NA, NA, "d", "e", NA, "f", NA, "g", NA))
for (j in 2:4){
for (i in 1:10){
if(is.na(testdata[i, j])){
testdata[i, j] <- testdata[i - 1, j]
}}}
Цикл for работает нормально, однако я обобщу этот код и напишу его в функции, которая создаст пустой список. Я написал следующую функцию:
fill_null <- function(df, columns, rows){
for (j in columns){
for(i in rows){
if(is.na(df[i, j])){
df[i,j] <- df[i - 1, j]
} else{
df[i, j] <- df[i, j]
}}}}
Когда я запускаю эту функцию, используя следующий код:
newdf <- fill_null(testdata, 2:4, 1:10)
str(newdf)
Получаю следующий результат:
> str(newdf)
NULL
Мне интересно, почему этот цикл for будет работать, если он не вызывается в функции, но перестает работать после того, как он записан в функцию. Мне также интересно, есть ли простой способ решить эту проблему, потому что мне нужно заполнить NA запаздывающими значениями для нескольких разных фреймов данных.
return(df)
в конце вашей функции. - person Gregor Thomas   schedule 16.10.2019zoo::na.locf
(для одного столбца) илиtidyr::fill
(для всего фрейма данных), которые делают это с большим количеством функций и более эффективно. См., Например, этот FAQ по этой теме. Ваша функция делает то же самое, что иtidyr::fill(testdata)
- person Gregor Thomas   schedule 16.10.2019NA
значения. - person Gregor Thomas   schedule 16.10.2019for
илиlapply
, например,testdata[columns] = lapply(testdata[columns], simple_fill_null)
. Или, если вам действительно нужен интерфейс столбца, напишите оболочку, которая делает этоlapply
. Небольшие размеры и модульность функций упрощают их отладку и делают их более гибкими в использовании. - person Gregor Thomas   schedule 14.11.2019