Change values in df to 0 = FALSE, 1 = TRUE, 2 = TRUE

Viewed 2653

I have a dataframe containing 0, 1 and 2s. My goal is to switch those values so instead it shows FALSE for 0 and TRUE for 1 or 2.

I tried deplyr`s case_when but it did not deliver the hoped for result.

test <- data.frame("ID" = c("A", "B", "C", "D"),
                "Primary" = c(0,0,2,1),
               "Secondary" = c(1,0,1,2),
               "Tertiary" = c(2,1,0,0))

test <- case_when(
 test$Primary == 0 ~ "FALSE",
 test$Primary != 0 ~ "TRUE",
 test$Secondary == 0 ~ "FALSE",
 test$Secondary != 0 ~ "TRUE",
 test$Secretory == 0 ~ "FALSE",
 test$Secretory != 0 ~ "TRUE",
 test$Tertiary == 0 ~ "FALSE",
 test$Tertiary != 0 ~ "TRUE")

The code above gave me one character vector with all results in one line but I would like to have the df structure to be maintained.

3 Answers

This is quite easy in base R:

test[,-1] <- lapply(test[,-1], as.logical)

By default, 0 corresponds to FALSE, and all other values to TRUE, so as.logical does it for you. Probably it is easy to do it with dplyr as well, you definitely don't need that many lines in `case_when´.

In base R one could do:

test[-1] <- test[-1] > 0
test
#   ID Primary Secondary Tertiary
# 1  A   FALSE      TRUE     TRUE
# 2  B   FALSE     FALSE     TRUE
# 3  C    TRUE      TRUE    FALSE
# 4  D    TRUE      TRUE    FALSE

If you insist on dplyr + case_when you could do:

test[-1] <- 
  test %>%
  select(-"ID") %>%
  mutate_all(
    funs(
      case_when(
        . == 0 ~ FALSE,
        . %in% 1:2 ~ TRUE
      )
    )
  )

You can use mutate_if to change numeric columns to their logical equivalents:

test %>% mutate_if(is.numeric,as.logical)
  ID Primary Secondary Tertiary
1  A   FALSE      TRUE     TRUE
2  B   FALSE     FALSE     TRUE
3  C    TRUE      TRUE    FALSE
4  D    TRUE      TRUE    FALSE
Related