简体   繁体   中英

How to mutate some values of a dataframe based on values from another dataframe column with R

I want to transform df1$x using df2$x to obtain df3 . But I am certainly wrong when using mutate this way.

library(tidyverse)
df1 <- tibble(year = c(2019, 2019, 2020, 2020),
              x = c("0123", "0222", "0144", "0124"))
df2 <- tibble(x = c("22", "24"))

# I want to obtain
df3 <- tibble(year = c(2019, 2019, 2020, 2020),
              x = c("0123", "0222", "0144", NA))

# but this mutate does not work
df1 %>%
  mutate(x = if_else(str_sub(x,3,4) %in% df2$x & year == 2020, NA, x))
#> Error: Problem with `mutate()` input `x`.
#> x `false` must be a logical vector, not a character vector.
#> i Input `x` is `if_else(str_sub(x, 3, 4) %in% df2$x & year == 2020, NA, x)`.
Created on 2020-10-26 by the reprex package (v0.3.0)

The if_else does type checks. According to ?if_else

Compared to the base ifelse(), this function is more strict. It checks that true and false are the same type. This strictness makes the output type more predictable, and makes it somewhat faster.

and NA by default returns NA_logical_ .

typeof(NA)
#[1] "logical"

According to ?NA

NA is a logical constant of length 1 which contains a missing value indicator. NA can be coerced to any other vector type except raw. There are also constants NA_integer_, NA_real_, NA_complex_ and NA_character_ of the other atomic vector types which support missing values: all of these are reserved words in the R language.

We need NA_character_ specifically as there is no coercing to appropriate type (which would normally work with base R ifelse )

typeof(NA_character_)
#[1] "character"

Therefore, it is better to use the appropriate type matched NA

library(dplyr)
df1 %>%
    mutate(x = if_else(str_sub(x,3,4) %in% df2$x &
              year == 2020, NA_character_, x))

The ifelse doesn't have that issue as the NA automatically is converted to NA_character_

df1 %>%
  mutate(x = ifelse(str_sub(x,3,4) %in% df2$x & year == 2020, NA, x))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM