Home > Software design >  How to set the value of a list to NA, depending on value in another column
How to set the value of a list to NA, depending on value in another column

Time:07-09

I have a dataframe df_list which contains a column cars of class list. I want to set the value of the list in column cars to NA if the value in column gear is equal to 3.

Below some of my attempts with na_if, case_when and map_if. The closest I get to is to set all elements of the list to NA. However, I would like to have only one NA.

Grateful for any suggestions!

library(tidyverse)

df_list <- mtcars %>%
  rownames_to_column(., var="car") %>%
  group_by(gear) %>%
  summarise(cars=list(car))

df_list
# A tibble: 3 × 2
#    gear cars      
#   <dbl> <list>
# 1     3 <chr [15]>
# 2     4 <chr [12]>
# 3     5 <chr [5]>


df_list %>%
  mutate(cars_2=case_when(
      gear==3 ~ NA,
      TRUE ~ cars))
# Error in `mutate()`:
# ! Problem while computing `cars_2 = case_when(gear == 3 ~ NA, TRUE ~ cars)`.
# Caused by error in `` names(message) <- `*vtmp*` ``:
# ! 'names' attribute [1] must be the same length as the vector [0]
# Run `rlang::last_error()` to see where the error occurred.


df_list %>%
  mutate(cars_2=case_when(
      gear==3 ~ map(cars, NA),
      TRUE ~ cars))
# Error in `mutate()`:
# ! Problem while computing `cars_2 = case_when(gear == 3 ~ map(cars, NA), TRUE ~ cars)`.
# Caused by error in `as_mapper()`:
# ! Can't convert `.f`, `NA`, to a function.
# Run `rlang::last_error()` to see where the error occurred.


#sets all elements of the list to NA
df_list_na <- df_list %>%
  mutate(gear_3=str_detect(gear, "3")) %>%
  mutate(cars_2=map_if(cars, .p=gear_3, function(x) dplyr::na_if(x, x))) 
  df_list_na$cars_2
# [[1]]
#  [1] NA NA NA NA NA NA NA NA NA NA NA NA NA NA NA 
# [[2]]
#  [1] "Mazda RX4"      "Mazda RX4 Wag"  "Datsun 710"     "Merc 240D"
#  [5] "Merc 230"       "Merc 280"       "Merc 280C"      "Fiat 128"
#  [9] "Honda Civic"    "Toyota Corolla" "Fiat X1-9"      "Volvo 142E"
# [[3]]
# [1] "Porsche 914-2"  "Lotus Europa"   "Ford Pantera L" "Ferrari Dino"
# [5] "Maserati Bora"

CodePudding user response:

Or simply like this:

df_list$cars[df_list$gear==3] <- NA

CodePudding user response:

You can just use ifelse:

df_list %>% 
  mutate(cars = ifelse(gear == 3, NA, cars))

This gives:

[[1]]
[1] NA

[[2]]
 [1] "Mazda RX4"      "Mazda RX4 Wag"  "Datsun 710"     "Merc 240D"      "Merc 230"       "Merc 280"       "Merc 280C"      "Fiat 128"      
 [9] "Honda Civic"    "Toyota Corolla" "Fiat X1-9"      "Volvo 142E"    

[[3]]
[1] "Porsche 914-2"  "Lotus Europa"   "Ford Pantera L" "Ferrari Dino"   "Maserati Bora" 
  • Related