my code looks like this:
library(tidyverse)
df <- read.table(header=TRUE, text='
subject sex control q1 q2
1 M 7.9 1 1
2 F 6.3 2 3
3 F 9.5 3 1
4 M 11.5 7 6
')
df %>% mutate_all(~case_when(
. == 1 ~ 7,
. == 7 ~ 1,
TRUE ~ . )
)
I want to replace all 1 with 7 and vice versa but keep everything else.
The error states:
Error: Problem with
mutate()
columnsubject
. isubject = (structure(function (..., .x = ..1, .y = ..2, . = ..1) ...
. x must be a double vector, not an integer vector.
A solution indicates
TRUE ~ as.numeric(as.character(.)) )
works, but then the sex colum is NA
How can I fix this?
Edit (add):
A suggestion was to use nested if-else, which would work, but I really hope there is a better solution than:
df %>% mutate_all(~ifelse(. == 1, 7, ifelse(. == 7, 1, .)))
imagine a long list of values to be replaced.
CodePudding user response:
You can use either mutate_at()
or mutate_if()
to selectively choose which columns to apply the transformation to.
df %>% mutate_at(c(3:5), ~case_when(
. == 1 ~ 7,
. == 7 ~ 1,
TRUE ~ as.numeric(.))
)
df %>% mutate_if(is.numeric, ~case_when(
. == 1 ~ 7,
. == 7 ~ 1,
TRUE ~ as.numeric(.))
)
Edit: a non-deprecated version without mutate_if would be:
df %>% mutate(
across(
where(is.numeric),
~case_when(
. == 1 ~ 7,
. == 7 ~ 1,
TRUE ~ as.numeric(.)
)
)
)
CodePudding user response:
Try this:
df %>%
mutate(across(starts_with("q"),
~ ifelse(. == 1, 7,
ifelse(. == 7, 1, .))
))
subject sex control q1 q2
1 1 M 7.9 7 7
2 2 F 6.3 2 3
3 3 F 9.5 3 7
4 4 M 11.5 1 6
A column-name independent solution is this:
df %>%
mutate(across(where(is.integer),
~ ifelse(. == 1, 7,
ifelse(. == 7, 1, .))
))
CodePudding user response:
I would use a nested ifelse()
call along with lapply()
here:
cols <- c("q1", "q2") # or whatever columns you want
df[cols] <- lapply(df[cols], function(x) ifelse(x == 1, 7, ifelse(x == 7, 1, x)))
CodePudding user response:
You could wrap the mutate_all
in a function, to skip the characters e.g.
custom_fun <- function(x){
if(is.integer(x)|is.numeric(x)){
case_when(
x == 1 ~ 7,
x == 7 ~ 1,
TRUE ~ as.numeric(x)
)
}else{
x
}
}
df %>% mutate_all(custom_fun)