#r #dplyr
#r #dplyr
Вопрос:
У меня есть следующие данные:
library(dplyr)
d <- data_frame(
region = c('all', 'nj', 'rkl', 'all'),
figures= c(5, 7, 4, 8),
figures2 = c(3, 5, 6, 7))
Я хотел бы использовать dplyr, чтобы указать, когда ‘region’ = ‘all’, затем преобразовать ‘figures’ и ‘figures2’ в ‘x’. Я не хочу использовать mutate для создания новых переменных, я хочу изменить значения в переменных, которые уже существуют. Таким образом, данные будут выглядеть следующим образом:
d2 <- data_frame(
region = c('all', 'nj', 'rkl', 'all'),
figures= c(x, 7, 4, x),
figures2 = c(x, 5, 6, x))
Я думаю, мне нужно что-то вроде этого:
d %>% mutate_at(vars(1:3), funs(ifelse(region = 'all', 'x', .)))
Однако это не совсем работает.
Комментарии:
1.
d %>% mutate_at(vars(2:3), list(~ ifelse(region == 'all', 'x', .)))
не тестировал, но попробуйте2. Есть причина, по которой вы не выполняете два
mutate
s? Один дляfigures
и один дляfigures2
? Если у вас есть еще много таких столбцов, подумайте оgather
преобразовании ваших столбцов в длинный формат.3. вы правы — я просто сделал это до того, как вы опубликовали, и это сработало. Я удалю сообщение, поскольку на этот вопрос есть ответ в другом месте. Спасибо
Ответ №1:
Вы были на правильном пути с mutate_at
:
d %>%
mutate_at(vars(2:3), list(~ ifelse(region == 'all', 'x', .)))
Вывод:
# A tibble: 4 x 3
region figures figures2
<chr> <chr> <chr>
1 all x x
2 nj 7 5
3 rkl 4 6
4 all x x
Вы можете просто заменить 'x'
числом, если это необходимо.
Редактировать.
- Я также думаю, что это
replace
лучшая альтернатива, вы могли бы просто сделатьd %>%
то же самое;
mutate_at(vars(2:3), list(~ replace(., region == 'all', 'x'))) - Более того, как отметил @Moody_Mudskipper, нет необходимости в
list
новейшейdplyr
версии, поэтомуmutate_at(2:3, ~ ifelse(region == 'all', 'x', .))
также справился бы с этой задачей.
Комментарии:
1. С последней версией dplyr вам не нужно переносить свою формулу в список для доступа к другим столбцам в
mutate_at
. Также нет необходимости использоватьvars
с числовыми индексами. Так что это нормально :d %>% mutate_at(2:3, ~ ifelse(region == 'all', 'x', .))
2. Спасибо @Moody_Mudskipper, не знал об этом — изменю это!
Ответ №2:
Один из способов с mutate
и replace
:
d %>%
mutate(figures = replace(figures, region == 'all', 10)) %>%
mutate(figures2 = replace(figures2, region == 'all', 10))
# A tibble: 4 x 3
region figures figures2
<chr> <dbl> <dbl>
1 all 10 10
2 nj 7 5
3 rkl 4 6
4 all 10 10
Я использую 10 здесь в качестве вашего x
Комментарии:
1. Да, это тоже хорошо, дает немного больше контроля, если вы хотите заменить разные столбцы разными значениями
Ответ №3:
Вариантом было бы также использовать case_when
library(dplyr)
d %>%
mutate_if(is.numeric, list(~ case_when(region == "all" ~ 'x',
TRUE ~ as.character(.) )))
# A tibble: 4 x 3
# region figures figures2
# <chr> <chr> <chr>
#1 all x x
#2 nj 7 5
#3 rkl 4 6
#4 all x x
base R
Компактным вариантом было бы
d[d$region == "all", -1] <- "x"