R как заполнить АН с правилами - PullRequest
1 голос
/ 18 июня 2019
data=data.frame(person=c(1,1,1,2,2,2,2,3,3,3,3),
t=c(3,NA,9,4,7,NA,13,3,NA,NA,12),
WANT=c(3,6,9,4,7,10,13,3,6,9,12))

Таким образом, в основном я хочу создать новую переменную 'WANT', которая принимает значение PREVIOUS в t и ADDS 3 к нему, и если в строке много NA, то она продолжает это делать.Моя попытка:

library(dplyr)
data %>% 
  group_by(person) %>% 
  mutate(WANT_TRY = fill(t) + 3)

Ответы [ 4 ]

1 голос
/ 18 июня 2019

Вот другой способ. Мы можем сделать линейную интерполяцию с пакетом imputeTS.

library(dplyr)
library(imputeTS)

data2 <- data %>%
  group_by(person) %>%
  mutate(WANT2 = na.interpolation(WANT)) %>%
  ungroup()

data2
# # A tibble: 11 x 4
#    person     t  WANT WANT2
#     <dbl> <dbl> <dbl> <dbl>
#  1      1     3     3     3
#  2      1    NA     6     6
#  3      1     9     9     9
#  4      2     4     4     4
#  5      2     7     7     7
#  6      2    NA    10    10
#  7      2    13    13    13
#  8      3     3     3     3
#  9      3    NA     6     6
# 10      3    NA     9     9
# 11      3    12    12    12
1 голос
/ 18 июня 2019

Вот один из способов -

data %>% 
  group_by(person) %>%
  mutate(
    # cs = cumsum(!is.na(t)), # creates index for reference value; uncomment if interested
    w = case_when(
      # rle() gives the running length of NA
      is.na(t) ~ t[cumsum(!is.na(t))] + 3*sequence(rle(is.na(t))$lengths),
      TRUE ~ t
      )
  ) %>% 
  ungroup()

# A tibble: 11 x 4
   person     t  WANT     w
    <dbl> <dbl> <dbl> <dbl>
 1      1     3     3     3
 2      1    NA     6     6
 3      1     9     9     9
 4      2     4     4     4
 5      2     7     7     7
 6      2    NA    10    10
 7      2    13    13    13
 8      3     3     3     3
 9      3    NA     6     6
10      3    NA     9     9
11      3    12    12    12
0 голосов
/ 18 июня 2019

Вы можете использовать функциональное программирование из purrr и добавление «NA-safe» из hablar:

library(hablar)
library(dplyr)
library(purrr)

data %>% 
  group_by(person) %>% 
  mutate(WANT2 = accumulate(t, ~.x %plus_% 3))

Результат

# A tibble: 11 x 4
# Groups:   person [3]
   person     t  WANT WANT2
    <dbl> <dbl> <dbl> <dbl>
 1      1     3     3     3
 2      1    NA     6     6
 3      1     9     9     9
 4      2     4     4     4
 5      2     7     7     7
 6      2    NA    10    10
 7      2    13    13    13
 8      3     3     3     3
 9      3    NA     6     6
10      3    NA     9     9
11      3    12    12    12
0 голосов
/ 18 июня 2019

Это сложнее, чем кажется из-за двойного NA в конце. Если бы не это, то следующее:

ifelse(is.na(data$t), c(0, data$t[-nrow(data)])+3, data$t)

... дал бы вам, что вы хотите. Самый простой способ, который использует ту же логику, но выглядит не очень умно (извините!):

.impute <- function(x) ifelse(is.na(x), c(0, x[-length(x)])+3, x)
.impute(.impute(data$t))

... который просто обманывает, делая это дважды. Это помогает?

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