#r #string #replace #numbers #recode
#r #строка #заменить #числа #перекодировать
Вопрос:
Мне нужно заменить строки числами в нескольких столбцах. Ниже приведен пример набора данных:
x <- c("Low Outlier", "High Outlier", "Novice", "Novice", "Emerging", NA, "Proficient", "Approaching")
y <- c("Novice", "Approaching", "Proficient", "Approaching", "High Outlier", "Proficient",NA, "Emerging")
z <- c("High Outlier", "Proficient", "Approaching", "Emerging", "Low Outlier", "Approaching", "Approaching", "Emerging")
sam <- cbind(x,y,z)
Мне нужно преобразовать «высокие / низкие выбросы» в 0, NA должны быть оставлены как NA, «Новичок» в 1, «Начинающий» в 2, «Приближающийся к 3» и «Опытный» в 4.
Я попытался преобразовать одну переменную с
sam$x.r <- recode(sam$x.r,'Low Outlier'=0,'High Outlier'=0,'Novice'=1,'Emerging'=2,'Approaching'=3, 'Proficient'=4)
Я получил сообщение об ошибке «Предупреждающее сообщение:
В recode.numeric(Dat17_18.1 $Т.Е.ScoreStat, Low Outlier
= 0, High Outlier
= 0, :
NAs, введенный принудительно»
Я не уверен, как перекодировать все переменные сразу.
Ответ №1:
Просто сделайте это-
sam[] <- recode(sam,'Low Outlier'=0,
'High Outlier'=0,
'Novice'=1,
'Emerging'=2,
'Approaching'=3,
'Proficient'=4)
> sam
x y z
[1,] "0" "1" "0"
[2,] "0" "3" "4"
[3,] "1" "4" "3"
[4,] "1" "3" "2"
[5,] "2" "0" "0"
[6,] NA "4" "3"
[7,] "4" NA "3"
[8,] "3" "2" "2"
Ответ №2:
Очень быстро стало повторяться. Вот простая функция:
my_replacer<-function(df,y,z){
df<-as.data.frame(apply(df,2,function(x) gsub(y,z,x)))
#y is what you want to replace
#z is the replacement
#This uses regex
df
}
my_replacer(sam,"Emerging.*","2")
Вот как я это использовал:
library(dplyr)#can use ifelse. Still repetitive
sam<-as.data.frame(sam)
sam %>%
mutate_if(is.factor,as.character)->sam
my_replacer(sam,"Emerging.*","2")
Результат:
x y z
1 Low Outlier Novice High Outlier
2 High Outlier Approaching Proficient
3 Novice Proficient Approaching
4 Novice Approaching 2
5 2 High Outlier Low Outlier
6 <NA> Proficient Approaching
7 Proficient <NA> Approaching
8 Approaching 2 2
Заменить другие:
my_replacer(sam,"Novi.*","1")
x y z
1 Low Outlier 1 High Outlier
2 High Outlier Approaching Proficient
3 1 Proficient Approaching
4 1 Approaching Emerging
5 Emerging High Outlier Low Outlier
6 <NA> Proficient Approaching
7 Proficient <NA> Approaching
8 Approaching Emerging Emerging
Ответ №3:
Мы можем использовать case_when
from dplyr
для таких случаев
library(dplyr)
sam %>%
mutate_all(~case_when(. %in% c("Low Outlier", "High Outlier") ~ '0',
. == "Novice" ~ '1',
. == "Emerging" ~ '2',
. == "Approaching" ~ '3',
. == "Proficient" ~ '4',
TRUE ~ NA_character_))
# x y z
#1 0 1 0
#2 0 3 4
#3 1 4 3
#4 1 3 2
#5 2 0 0
#6 <NA> 4 3
#7 4 <NA> 3
#8 3 2 2
Однако конечный результат содержит символьные столбцы, поскольку наши исходные столбцы также были символами. Мы можем добавить mutate_all(as.numeric)
, чтобы преобразовать их в числовые, если это необходимо.
данные
x <- c("Low Outlier", "High Outlier", "Novice", "Novice", "Emerging", NA,
"Proficient", "Approaching")
y <- c("Novice", "Approaching", "Proficient", "Approaching", "High Outlier",
"Proficient",NA, "Emerging")
z <- c("High Outlier", "Proficient", "Approaching", "Emerging", "Low Outlier",
"Approaching", "Approaching", "Emerging")
sam <- data.frame(x,y,z, stringsAsFactors = FALSE)
Ответ №4:
Я бы использовал именованные векторы в качестве сопоставления
library(dplyr)
mapping = c("High Outlier" = 0, "Low Outlier" = 0, "Novice" = 1, "Emerging" = 2, "Approaching" = 3, "Proficient" = 4)
sam %>%
as.data.frame() %>%
mutate_all(function(i) mapping[i])
Ответ №5:
Другое решение, использующее factors
для перекодирования и approxfun
присвоения значений:
sam[] <- approxfun(1:5, c(0:3, 0))(
as.numeric(factor(sam,
c("Low Outlier", "Novice",
"Emerging", "Approaching",
"Proficient", "High Outlier"))))
# x y z
# [1,] "0" "1" NA
# [2,] NA "3" "0"
# [3,] "1" "0" "3"
# [4,] "1" "3" "2"
# [5,] "2" NA "0"
# [6,] NA "0" "3"
# [7,] "0" NA "3"
# [8,] "3" "2" "2"