This is my data frame:
library(zoo)
library(dplyr)
df <- data.frame(
id = rep(1:4, each = 4),
status = c(
NA, "a", "c", "a",
NA, "c", "c", "c",
NA, NA, "a", "c",
NA, NA, "c", "c"),
otherVar = letters[1:16],
stringsAsFactors = FALSE)
For the variable status I want the next observation to be carried backward within group (id).
df %>% group_by(id) %>% na.locf(fromLast = TRUE) %>% ungroup
However, I want only my "c" 's to be carried backwards but not "a" 's.
From variable status:
NA "a" "c" "a" NA "c" "c" "c" NA NA "a" "c" NA NA "c" "c"
I want to get:
NA "a" "c" "a" "c" "c" "c" "c" NA NA "a" "c" "c" "c" "c" "c"
Respectively:
data.frame(
id = rep(1:4, each = 4),
status = c(
NA, "a", "c", "a",
"c", "c", "c", "c",
NA, NA, "a", "c",
"c", "c", "c", "c"),
otherVar = letters[1:16],
stringsAsFactors = FALSE)
Is there a way of doing this?
After applying na.locf0
check each position that was NA
and if it is now a
reset it back to NA
. If you want to overwrite status
then replace the second status2=
line with status = if_else(is.na(status) & status2 == "a", NA_character_, status2), status2 = NULL) %>%
library(dplyr)
library(zoo)
df %>%
group_by(id) %>%
mutate(status2 = na.locf0(status, fromLast = TRUE),
status2 = if_else(is.na(status) & status2 == "a", NA_character_, status2)) %>%
ungroup
giving:
# A tibble: 16 x 4
id status otherVar status2
<int> <chr> <chr> <chr>
1 1 <NA> a <NA>
2 1 a b a
3 1 c c c
4 1 a d a
5 2 <NA> e c
6 2 c f c
7 2 c g c
8 2 c h c
9 3 <NA> i <NA>
10 3 <NA> j <NA>
11 3 a k a
12 3 c l c
13 4 <NA> m c
14 4 <NA> n c
15 4 c o c
16 4 c p c