Заменить строки значениями в нескольких столбцах одновременно - PullRequest
3 голосов
/ 11 апреля 2019

Мне нужно заменить строки числами в нескольких столбцах. Ниже приведен пример набора данных:

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 $ I.E.ScoreStat, Low Outlier = 0, High Outlier = 0,: НС введены по принуждению "

Я не уверен, как перекодировать все переменные одновременно.

Ответы [ 5 ]

4 голосов
/ 11 апреля 2019

Просто сделай это -

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 голосов
/ 11 апреля 2019

Получил действительно повторение очень быстро.Вот простая функция:

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
2 голосов
/ 11 апреля 2019

Мы можем использовать case_when из 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), чтобы преобразовать их в числовые при необходимости.

data

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)
1 голос
/ 11 апреля 2019

Я бы использовал именованные векторы в качестве отображения

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])
0 голосов
/ 11 апреля 2019

Другое решение, использующее 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"
...