#r #dplyr #tidyverse #tidyr #purrr
#r #dplyr #tidyverse #tidyr #муррр
Вопрос:
Я хочу заменить значения в определенных столбцах фрейма данных. Я могу сделать это один раз, но он перестает работать, как только я пытаюсь создать функцию. Я также хотел бы повторить функцию для подмножества всех столбцов, и я тоже не уверен, как это сделать.
Вот пример:
library(tidyverse)
Kid = c('Alfie', 'Brenda', 'Charlie', 'Dalma')
Likes_pie = c('Yes', 'Yes', 'No', NA)
Likes_sunshine = c(NA, 'Yes', 'Yes', 'No')
Likes_friendship = c('Yes', NA, 'Yes', 'No')
my.d = cbind(Kid, Likes_pie, Likes_sunshine) %>% as_tibble()
Я хочу поменять местами «Да» на «T» и «Нет» на «F» в Likes_pie
и Likes_sunshine
. Но я хочу указать эти два столбца и исключить Likes_friendship
. Я хочу сохранить NA-s. Нет никаких значений, кроме «Да» и «Нет».
Можно обойтись одним столбцом:
my.d = my.d %>%
mutate(
Likes_pie = case_when(
Likes_pie == 'Yes' ~ 'T',
Likes_pie == 'No' ~ 'F'
)
)
Но это не работает в функции:
valConverter = function(d, var.value){
d = d %>%
mutate(
var.value = case_when(
var.value == 'Yes' ~ 'T',
var.value == 'No' ~ 'F'
)
)
return(d)
}
my.d = valConverter(my.d, Likes_sunshine)
my.d$Likes_pie
my.d$Likes_sunshine # :E
Предполагая, что это так, как мне заменить значения столбцов для каждого столбца?
Является ли sg таким mutate_if(d, c('Likes_pie', 'Likes_sunshine'), function(x) nomConverter(x))
способом?
Комментарии:
1. Включен ли
Likes_friendship
один из столбцовmy.d
?2. да, это так. моя ошибка.
Ответ №1:
Решение с использованием lapply
и ifelse
. Я предполагаю Likes_friendship
, что это один из столбцов (иначе зачем вы создали этот вектор?), Но находится ли столбец в фрейме данных, не влияет на эффективность этого решения.
Кстати T
, and F
— это зарезервированное слово в R, указывающее логическое значение TRUE
и FALSE
, соответственно. Символ "T"
и "F"
может привести других в замешательство.
# Store the column name you want to change
cols <- c("Likes_pie", "Likes_sunshine")
my.d[cols] <- lapply(my.d[cols], function(x) ifelse(x == "Yes", "T", "F"))
my.d
# # A tibble: 4 x 4
# Kid Likes_pie Likes_sunshine Likes_friendship
# <chr> <chr> <chr> <chr>
# 1 Alfie T NA Yes
# 2 Brenda T T NA
# 3 Charlie F T Yes
# 4 Dalma NA F No
ДАННЫЕ
library(tidyverse)
Kid = c('Alfie', 'Brenda', 'Charlie', 'Dalma')
Likes_pie = c('Yes', 'Yes', 'No', NA)
Likes_sunshine = c(NA, 'Yes', 'Yes', 'No')
Likes_friendship = c('Yes', NA, 'Yes', 'No')
my.d = cbind(Kid, Likes_pie, Likes_sunshine, Likes_friendship) %>% as_tibble()
Комментарии:
1. Если вы хотите ускорить его / иметь тонну данных и сохранить
"T"
и"F"
как символы, вы также можете использоватьlapply(my.d[cols], function(x) c("F", "T")[(x == "Yes") 1])
или, может быть, дажеlapply(lapply(my.d[cols], `==`, "Yes"), as.character)
. Я знаю, что скорость не была целью, я просто хотел добавить пару похожих решений 🙂2. @Andrew Спасибо, что поделились. Эти два являются разумными решениями.
Ответ №2:
Не могли бы вы просто использовать mutate_all
?
my.d %>%
mutate_all(~case_when(
.x == "Yes" ~ "T",
.x == "No" ~ "F",
TRUE ~ .x))
## A tibble: 4 x 3
# Kid Likes_pie Likes_sunshine
# <chr> <chr> <chr>
#1 Alfie T NA
#2 Brenda T T
#3 Charlie F T
#4 Dalma NA F
Или для определенных столбцов используйте mutate_at
cols <- c("Likes_pie", "Likes_sunshine")
my.d %>%
mutate_at(vars(cols), ~case_when(
.x == "Yes" ~ "T",
.x == "No" ~ "F",
TRUE ~ .x))
дает тот же результат.
Ответ №3:
Вы могли бы использовать mutate_at()
для этого один раз, an ifelse
тоже будет делать то, что вы хотите:
(my.d <- tibble(Kid, Likes_pie, Likes_sunshine, Likes_friendship) %>%
mutate_at(c("Likes_pie", "Likes_sunshine"), list(~ifelse(. == "Yes", T, F))))
# A tibble: 4 x 4
Kid Likes_pie Likes_sunshine Likes_friendship
<chr> <lgl> <lgl> <chr>
1 Alfie TRUE NA Yes
2 Brenda TRUE TRUE NA
3 Charlie FALSE TRUE Yes
4 Dalma NA FALSE No
Ответ №4:
Если предполагается преобразовать в логический столбец, просто выполните ==
library(dplyr)
my.d %>%
mutate_at(vars(cols), list(~ . == "Yes"))
где
cols <- c("Likes_pie", "Likes_sunshine")