Обновление последних значений группы - PullRequest
0 голосов
/ 14 марта 2020

У меня есть фрейм данных, где я пытаюсь заменить NA значениями, основанными на некоторых условиях. По какой-то причине я получаю больше NA.

Датафрейм выглядит следующим образом:

Employee.ID ta_start    prv_state   nxt_state   border_chk
33          10/24/2017  WYOMING     COLORADO    1
33          5/20/2019   WYOMING     NA          NA
19421       12/6/2019   TEXAS       TEXAS       NA
19421       12/17/2019  TEXAS       TEXAS       1
19421       1/6/2020    TEXAS       TEXAS       1
19421       1/30/2020   TEXAS       NA          NA

Я хочу, чтобы вывод был таким:

Employee.ID ta_start    prv_state   nxt_state   border_chk
33          10/24/2017  WYOMING     COLORADO    1
33          5/20/2019   WYOMING     COLORADO    1
19421       12/6/2019   TEXAS       TEXAS       NA
19421       12/17/2019  TEXAS       TEXAS       1
19421       1/6/2020    TEXAS       TEXAS       1
19421       1/30/2020   TEXAS       TEXAS       1

Этот код Я не получаю работу; он заменяет оба целевых столбца связкой NA:


ta_roll_up4a <- as.data.frame(ta_roll_up4 %>%
               group_by(Employee.ID) %>%
               arrange(ta_start) %>%
               dplyr::mutate(nxt_state = ifelse(nxt_state == dplyr::last(nxt_state), lag(nxt_state), nxt_state),
                             border_chk = ifelse(border_chk == dplyr::last(border_chk), 1, border_chk)) %>%
               arrange(Employee.ID, ta_start))

Неверный результат, который я сейчас получаю:

Employee.ID ta_start    prv_state   nxt_state   border_chk
33          10/24/2017  WYOMING     NA          NA
33          5/20/2019   WYOMING     NA          NA
19421       12/6/2019   TEXAS       NA          NA
19421       12/17/2019  TEXAS       NA          NA
19421       1/6/2020    TEXAS       NA          NA
19421       1/30/2020   TEXAS       NA          NA

Заранее благодарен за вашу помощь.

Обновление: я изменил ifelse с

mutate(nxt_state = ifelse(nxt_state = dplyr::last(nxt_state), lag(nxt_state), nxt_state), 
       border_chk = ifelse(border_chk = dplyr::last(border_chk), 1, border_chk))

на это, чтобы сделать их логическими утверждениями

mutate(nxt_state = ifelse(nxt_state == dplyr::last(nxt_state), lag(nxt_state), nxt_state), 
       border_chk = ifelse(border_chk == dplyr::last(border_chk), 1, border_chk))

Ответы [ 2 ]

0 голосов
/ 14 марта 2020

Мы можем group_by Employee.ID и заменить значение NA в последнем ряду его предыдущим значением.

library(dplyr)

df %>%
  group_by(Employee.ID) %>%
  mutate_at(vars(nxt_state, border_chk), 
            ~replace(., row_number() == n() & is.na(.), .[n() - 1]))

#  Employee.ID ta_start   prv_state nxt_state border_chk
#        <int> <fct>      <fct>     <fct>          <int>
#1          33 10/24/2017 WYOMING   COLORADO           1
#2          33 5/20/2019  WYOMING   COLORADO           1
#3       19421 12/6/2019  TEXAS     TEXAS             NA
#4       19421 12/17/2019 TEXAS     TEXAS              1
#5       19421 1/6/2020   TEXAS     TEXAS              1
#6       19421 1/30/2020  TEXAS     TEXAS              1

данные

df <- structure(list(Employee.ID = c(33L, 33L, 19421L, 19421L, 19421L, 
19421L), ta_start = structure(c(3L, 6L, 5L, 4L, 2L, 1L), .Label = c("1/30/2020", 
"1/6/2020", "10/24/2017", "12/17/2019", "12/6/2019", "5/20/2019"
), class = "factor"), prv_state = structure(c(2L, 2L, 1L, 1L, 
1L, 1L), .Label = c("TEXAS", "WYOMING"), class = "factor"), 
nxt_state = structure(c(1L,NA, 2L, 2L, 2L, NA), .Label = c("COLORADO", "TEXAS"), 
class = "factor"), border_chk = c(1L, NA, NA, 1L, 1L, NA)), 
class = "data.frame", row.names = c(NA, -6L))
0 голосов
/ 14 марта 2020

В коде OP ifelse test не является логическим (согласно ?ifelse - тест - объект, который может быть приведен в логический режим)

library(dplyr)
library(tidyr)
library(lubridate)

На основе OP обновить, чтобы заменить только последние элементы NA, может создать. функция для `замены только последних значений NA на предыдущие не-NA

f1 <- function(x) {
      i1 <- cumsum(!is.na(x))
      i2 <- i1== max(i1)
      replace(x, which(i2)[-1], x[which(i2)[1]])
      }
ta_roll_up4 %>% 
   arrange(Employee.ID, mdy(ta_start)) %>%
   group_by(Employee.ID) %>% 
   mutate_at(vars(nxt_state, border_chk), f1)
# A tibble: 6 x 5
# Groups:   Employee.ID [2]
#  Employee.ID ta_start   prv_state nxt_state border_chk
#        <int> <chr>      <chr>     <chr>          <int>
#1          33 10/24/2017 WYOMING   COLORADO           1
#2          33 5/20/2019  WYOMING   COLORADO           1
#3       19421 12/6/2019  TEXAS     TEXAS              1
#4       19421 12/17/2019 TEXAS     TEXAS              1
#5       19421 1/6/2020   TEXAS     TEXAS              1
#6       19421 1/30/2020  TEXAS     TEXAS              1

или использование na.locf из zoo

library(zoo)
ta_roll_up4 %>%
  arrange(Employee.ID, mdy(ta_start)) %>%
  mutate(border_chk = replace(border_chk, 4, NA)) %>% # adding an NA in between
  group_by(Employee.ID) %>%
  mutate_at(vars(nxt_state, border_chk), ~ 
      case_when(row_number() >= last(which(!is.na(.))) ~ 
              na.locf0(.), TRUE ~ .))

data

ta_roll_up4 <- structure(list(Employee.ID = c(33L, 33L, 19421L, 19421L, 19421L, 
19421L), ta_start = c("10/24/2017", "5/20/2019", "12/6/2019", 
"12/17/2019", "1/6/2020", "1/30/2020"), prv_state = c("WYOMING", 
"WYOMING", "TEXAS", "TEXAS", "TEXAS", "TEXAS"), nxt_state = c("COLORADO", 
NA, "TEXAS", "TEXAS", "TEXAS", NA), border_chk = c(1L, NA, 1L, 
1L, 1L, NA)), class = "data.frame", row.names = c(NA, -6L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...