1

I'm trying to find a way to Replace NAs for a group of values with a non-NA character by group, if this non-NA character does not always appear in the same place (first row or other). The solutions I found don't work for characters or only fill based on a previous or subsequent value.

Here is an example of data:

participant_id <- c("ps1", "ps1", "ps1", "ps1", "ps2", "ps2", "ps3", "ps3", "ps3", "ps3")
test <- c("test1", NA, NA, NA, NA, "test2", NA, NA, "test3", NA)
data.frame(participant_id, test)

This is what I would like to end up with:

participant_id test
ps1 test1
ps1 test1
ps1 test1
ps1 test1
ps2 test2
ps2 test2
ps3 test3
ps3 test3
ps3 test3
ps3 test3
elmolibra
  • 39
  • 8

2 Answers2

2

We may use fill from tidyr after grouping by 'participant_id'

library(dplyr)
library(tidyr)
df1 <- df1 %>%
    group_by(participant_id) %>%
    fill(test, .direction = "downup") %>%
    ungroup

-output

df1
# A tibble: 10 × 2
   participant_id test 
   <chr>          <chr>
 1 ps1            test1
 2 ps1            test1
 3 ps1            test1
 4 ps1            test1
 5 ps2            test2
 6 ps2            test2
 7 ps3            test3
 8 ps3            test3
 9 ps3            test3
10 ps3            test3

data

df1 <- data.frame(participant_id, test)
akrun
  • 874,273
  • 37
  • 540
  • 662
2

Here is an alternative way using na.locf from zoo package:

library(zoo)
library(dplyr)
df %>% 
  group_by(participant_id) %>% 
  arrange(participant_id, test) %>% 
  mutate(test = zoo::na.locf(test, na.rm=FALSE))
   participant_id test 
   <chr>          <chr>
 1 ps1            test1
 2 ps1            test1
 3 ps1            test1
 4 ps1            test1
 5 ps2            test2
 6 ps2            test2
 7 ps3            test3
 8 ps3            test3
 9 ps3            test3
10 ps3            test3
TarJae
  • 72,363
  • 6
  • 19
  • 66