Обработка строк символов в числовые переменные в R - PullRequest
0 голосов
/ 05 марта 2019

Я пытался преобразовать 538 систему «оценки» опроса (от A + до F-, как школьные оценки) в серию чисел, используя операторы if-else и функции, как описано

here.

Я также пытался использовать функцию switch(), но ничего не помогло.Есть мысли о том, как это сделать?

Ответы [ 4 ]

0 голосов
/ 05 марта 2019

Вот как использовать match (на основе MCVE, предлагаемой Морисом:

 grades <- paste0(rep(LETTERS[c(1:4,6)], each = 3), c("+", "", "-"))[-c( 13)] # keep A+
 PollsFiltered$nums <- match(PollsFiltered$grade, rev(grades) ) # F(1) to A+(14)

> head(PollsFiltered)
  grade nums
1     B   10
2    C+    8
3    A+   14
4    A-   12
5    C+    8
6     B   10
0 голосов
/ 05 марта 2019

Лучше сделать левое соединение с lookup data.frame, содержащим сопоставления grade к gradenumber.Таким образом вы избежите многих ifelse утверждений.

Вот воспроизводимый пример:

# Grades
grades <- paste0(rep(LETTERS[c(1:4,6)], each = 3), c("+", "", "-"))[-c(1, 13)]
grades
#[1] "A"  "A-" "B+" "B"  "B-" "C+" "C"  "C-" "D+" "D"  "D-" "F"  "F-"

Генерация lookup data.frame

lookup <- data.frame(
    grade = grades,
    gradenumber = length(grades):1)

Мы сейчассгенерируйте некоторые образцы данных PollsFiltered, а затем left_join данные с lookup на grade.

set.seed(2018)
PollsFiltered <- data.frame(
    grade = sample(grades, 20, replace = T)
)

library(dplyr)
PollsFiltered %>%
    left_join(lookup, by = "grade")
#   grade gradenumber
#1     B-           9
#2      C           7
#3      A          13
#4     B+          11
#5      C           7
#6      B          10
#7     C-           6
#8     A-          12
#9     F-           1
#10    C-           6
#11    C+           8
#12    D+           5
#13    F-           1
#14    D+           5
#15    D-           3
#16    D+           5
#17     B          10
#18    C-           6
#19     D           4
#20    D-           3
0 голосов
/ 05 марта 2019

Еще один вариант использования dplyr - использовать оператор case_when следующим образом:

df$Num_grade <- NA
df <- mutate(df, Num_grade = case_when(
   grades == 'A' ~ 13,
   grades == 'A-' ~ 12,
   grades == 'B+' ~ 11,
   .
   .
   .
   grades == 'F-' ~ 1
))

, который очень похож на несколько операторов ifelse, но, на мой взгляд, легче понять

0 голосов
/ 05 марта 2019

Нет необходимости в ifelse, вы можете сделать следующее:

df$numericGrade = NA
df$numericGrade[df$grade=="A"] = 13
df$numericGrade[df$grade=="A-"] = 12
df$numericGrade[df$grade=="B+"] = 11
df$numericGrade[df$grade=="C-"] = 6

Например:

df = data.frame(Name = c("John", "Mary", "Timmy", "Susan"), grade = c("B+", "A", "C-", "DNF"))

   Name grade
1  John    B+
2  Mary     A
3 Timmy    C-
4 Susan   DNF

применение предыдущих строк приводит к:

   Name grade numericGrade
1  John    B+           11
2  Mary     A           13
3 Timmy    C-            6
4 Susan   DNF           NA

Конечно, это занимает одну строку для каждого случая, и мой пример не завершен.

Использование слияния

Другой вариант - использовать merge.В этом случае вам нужно иметь другой фрейм данных с преобразованием оценок:

gradesDict = data.frame(letter = c("A", "A-", "B+", "C-"),
                        number = c(13, 12, 11, 6))

  letter number
1      A     13
2     A-     12
3     B+     11
4     C-      6

, а затем выполнить:

df = merge(df, gradesDict, by.x = "grade", by.y = "letter", all.x = T)

  grade  Name number
1     A  Mary     13
2    B+  John     11
3    C- Timmy      6
4   DNF Susan     NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...