0

I have a data frame that looks like the below:

Word     Value1   Value2

Apple    True     True
Chair    True     False
nonWord  False    False
Hat      False    True
...      ...

I'm attempting to change all the values of nonWords to NA's.

data %>%
  mutate(Value1 = ifelse(Word == "nonWord", NA, Value1)) %>%
  mutate(Value2 = ifelse(Word == "nonWord", NA, Value2))

However, this does not seem to be working since my values are not being replaced by NA's. Does anyone know what I'm doing wrong?

Desired output:

Word     Value1   Value2

Apple    True     True
Chair    True     False
nonWord  NA       NA
Hat      False    True
...      ...
psychcoder
  • 543
  • 3
  • 14

2 Answers2

5

It's better to use replace() from base R rather than ifelse() for these cases:

library(dplyr)

df %>%
  mutate(Value1 = replace(Value1, Word == "nonWord", NA),
         Value2 = replace(Value2, Word == "nonWord", NA))

#>      Word Value1 Value2
#> 1   Apple   True   True
#> 2   Chair   True  False
#> 3 nonWord   <NA>   <NA>
#> 4     Hat  False   True

And if you're sure that all the columns you want to replace are named "Value...", you can take the advantage of mutate_at() from dplyr:

library(dplyr)

df %>%
  mutate_at(vars(starts_with("Value")), ~ replace(., Word == "nonWord", NA))

#>      Word Value1 Value2
#> 1   Apple   True   True
#> 2   Chair   True  False
#> 3 nonWord   <NA>   <NA>
#> 4     Hat  False   True

Data

df <- structure(list(Word = c("Apple", "Chair", "nonWord", "Hat"), 
    Value1 = c("True", "True", "False", "False"), Value2 = c("True", 
    "False", "False", "True")), class = "data.frame",
    row.names = c(NA, -4L))
2

Create a logical vector for rows in i (df1$Word == 'nonWord'), specify the column index in j (-1 - implies not selecting the 1st column) and assign the values to NA

df1[df1$Word == 'nonWord', -1] <- NA
df1
#     Word Value1 Value2
#1   Apple   True   True
#2   Chair   True  False
#3 nonWord   <NA>   <NA>
#4     Hat  False   True

Or using dplyr

library(dplyr) # 1.0.0
df1 <- df1 %>% 
       mutate(across(starts_with("Value"), ~ case_when(Word != 'nonWord' ~ .)))

In the OP's post, the replacement is happening, but the output is not assigned (<-) back to original object. By default, mutate is not modifying in place. If we want to do the in place modification, use %<>% from magrittr instead of %>%

data

df1 <- structure(list(Word = c("Apple", "Chair", "nonWord", "Hat"), 
    Value1 = c("True", "True", "False", "False"), Value2 = c("True", 
    "False", "False", "True")), class = "data.frame", row.names = c(NA, 
-4L))
akrun
  • 874,273
  • 37
  • 540
  • 662