Функция R, которая заменяет NA с запаздывающими значениями - PullRequest
0 голосов
/ 16 октября 2019

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

1 Ответ

0 голосов
/ 14 ноября 2019

В R функции будут (если не указано иное) возвращать последнее сгенерированное значение. В вашей функции вы можете думать, что последнее значение равно df, однако на самом деле это цикл for. Согласно документации в ?"for", петли for возвращают NULL в качестве значения. Простой способ продемонстрировать это - test <- for(x in 1:3){x}; test, который возвращает NULL.

. Чтобы исправить это, вы можете завершить свою функцию с помощью return(df) или просто df.

. Однако в основе вашей проблемы пакет dplyr имеет функцию lag, которая может оказаться вам полезной (testdata$j <- ifelse(is.na(testdata$j), lag(testdata$j), testdata$j)))

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