Замените NA предыдущим или следующим значением по группам, используя dplyr

У меня есть кадр данных, который упорядочен по убыванию порядка даты.

ps1 = data.frame(userID = c(21,21,21,22,22,22,23,23,23), color = c(NA,'blue','red','blue',NA,NA,'red',NA,'gold'), age = c('3yrs','2yrs',NA,NA,'3yrs',NA,NA,'4yrs',NA), gender = c('F',NA,'M',NA,NA,'F','F',NA,'F') ) 

Я хочу приписать (заменить) значения NA прежними значениями и сгруппировать по идентификатору пользователя. Если первая строка идентификатора пользователя имеет NA, то замените ее следующей совокупностью значений для этой группы userid.

Я пытаюсь использовать dplyr и zoo пакеты что-то вроде этого … но его не работает

 cleanedFUG % group_by(UserID) %>% mutate(Age1 = na.locf(Age), Color1 = na.locf(Color), Gender1 = na.locf(Gender) ) 

Мне нужен результат df следующим образом:

  userID color age gender 1 21 blue 3yrs F 2 21 blue 2yrs F 3 21 red 2yrs M 4 22 blue 3yrs F 5 22 blue 3yrs F 6 22 blue 3yrs F 7 23 red 4yrs F 8 23 red 4yrs F 9 23 gold 4yrs F 

     require(tidyverse) #fill is part of tidyr ps1 %>% group_by(userID) %>% fill(color, age, gender) %>% #default direction down fill(color, age, gender, .direction = "up") 

    Что дает вам:

     Source: local data frame [9 x 4] Groups: userID [3] userID color age gender     1 21 blue 3yrs F 2 21 blue 2yrs F 3 21 red 2yrs M 4 22 blue 3yrs F 5 22 blue 3yrs F 6 22 blue 3yrs F 7 23 red 4yrs F 8 23 red 4yrs F 9 23 gold 4yrs F 

    Использование zoo::na.locf непосредственно во всем файле data.frame будет заполнять NA независимо от групп userID . К сожалению, пакет dplyr не влияет на функцию na.locf , поэтому я пошел с na.locf :

     library(dplyr); library(zoo) ps1 %>% split(ps1$userID) %>% lapply(function(x) {na.locf(na.locf(x), fromLast=T)}) %>% do.call(rbind, .) #### userID color age gender #### 21.1 21 blue 3yrs F #### 21.2 21 blue 2yrs F #### 21.3 21 red 2yrs M #### 22.4 22 blue 3yrs F #### 22.5 22 blue 3yrs F #### 22.6 22 blue 3yrs F #### 23.7 23 red 4yrs F #### 23.8 23 red 4yrs F #### 23.9 23 gold 4yrs F 

    Что он делает, так это то, что он сначала разбивает данные на 3 data.frames, затем я применяю первый проход вменения (вниз), затем вверх с анонимной функцией в lapply и в конечном итоге использую rbind для возврата данных. У вас есть ожидаемый результат.

    Используя метод @agenis с na.locf() сочетании с purrr , вы можете сделать:

     library(purrr) library(zoo) ps1 %>% slice_rows("userID") %>% by_slice(function(x) { na.locf(na.locf(x), fromLast=T) }, .collate = "rows") 
    Interesting Posts

    Почему моя микроволновая печь убивает Wi-Fi?

    Различия между Java 8 Date Time API (java.time) и Joda-Time

    Алгоритм Дейкстры с отрицательными весами

    Как получить список IP-соединений, подключенных в одной сети (подсеть), используя Java

    Xcode – профиль iPhone не соответствует какой-либо действительной паре с сертификатом / закрытым ключом в ключевом ключе по умолчанию

    Почему я не могу отслеживать или получать доступ к определенным веб-сайтам в моем браузере, даже если я могу их пронести с терминала?

    CGContextDrawPDFPage занимает большую часть памяти

    Проверка блокировки учетной записи пользователя на другом контроллере домена

    Был найден недопустимый символ XML (Unicode: 0xc)

    Чтение образцов с помощью AVAssetReader

    Обезьяна патч в Rails 3

    Поддержка CORS в службах REST WCF

    ASP.NET: изменения Session.SessionID между запросами

    Настроить беспроводное сетевое решение для небольшого офиса (<30 человек)?

    Как установить или изменить версию Java (JDK) по умолчанию на OS X?

    Давайте будем гением компьютера.