Hello RStudio Community,
I'm a long-time reader and first-time question asker and am hoping you may be able to point me to a method to address an unusual case (to me at least).
I'd like to replace NA values from one row with values from another row for certain columns in a data frame. The motivation is survey data where there are multiple responses (in various stages of completion) for several individuals that I'd like to condense into one record per individual.
I've attached a toy example and function (my_fun
) below, which returns the desired output for one column at a time. What I'm having trouble with is expanding this into a function that I can purrr::map()
on multiple records (rows) and specific columns. I've outlined a goal_fun
to hopefully demonstrate what I'm trying to do (realize the rlang
syntax is incorrect).
While I've done my due diligence on SO and RSC, I haven't found an answer to address this. I suspect there is an elegant solution that I'm not seeing, and would greatly appreciate any recommendations you may have.
Thanks for reading.
Kurtis
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(purrr)
(df <- tibble(
guid = c("Bob_1", "Bob_2", "Judy"),
like_candy = c(NA, "Yes", "No"),
like_coffee = c(NA, "No", "Yes"),
like_beer = c("Yes", "Yes", "No"),
like_wine = c(NA, "Yes", NA)
))
#> # A tibble: 3 x 5
#> guid like_candy like_coffee like_beer like_wine
#> <chr> <chr> <chr> <chr> <chr>
#> 1 Bob_1 <NA> <NA> Yes <NA>
#> 2 Bob_2 Yes No Yes Yes
#> 3 Judy No Yes No <NA>
my_fun <- function(dat, guid, like_col) {
df <- dat
g <- guid
df %>%
mutate_at(
vars({{ like_col }}),
~case_when(
guid == g ~
df %>%
filter(guid == "Bob_2") %>%
pluck({{ like_col }}),
TRUE ~ .data[[{{ like_col }}]]
)
)
}
# Expected Result
my_fun(df, "Bob_1", "like_wine")
#> # A tibble: 3 x 5
#> guid like_candy like_coffee like_beer like_wine
#> <chr> <chr> <chr> <chr> <chr>
#> 1 Bob_1 <NA> <NA> Yes Yes
#> 2 Bob_2 Yes No Yes Yes
#> 3 Judy No Yes No <NA>
# This is the goal. For illustration purposes only.
goal_fun <- function(dat, target_record, source_record, cols_to_fix) {
df <- dat
c <- enquos(cols_to_fix)
df %>%
mutate_all(
vars(!!!c),
~case_when(
guid == target_record ~
df %>%
filter(guid == source_record) %>%
pluck(!!!c), # Realize this is not proper syntax
TRUE ~ .data[[!!!c]] # Ditto
)
)
}
Created on 2020-03-12 by the reprex package (v0.3.0)