Замена строки случайным числом из вектора - PullRequest
0 голосов
/ 15 июня 2019

У меня есть датафрейм, который включает в себя оценки студентов за курс. Эти оценки, однако, представлены в формате A-F и должны быть преобразованы в числовые оценки (10-1). Для этого я сгенерировал случайные числа, которые представляют эти значения A-F.

A <- rnorm(nrow(Student_Data), 9.45, 0.2)
B <- rnorm(nrow(Student_Data), 7.95, 0.2)
C <- rnorm(nrow(Student_Data), 6.25, 0.2)
D <- rnorm(nrow(Student_Data), 4.75, 0.2)
F <- rnorm(nrow(Student_Data), 2, 0.2)

Я также создал функцию, которая позволяет заменять буквы цифрами

courseGradesNumeric <- data.frame(lapply(courseGrades, function(x) {gsub("A", sample(A, 1), gsub("B", sample(B, 1), gsub("C", sample(C, 1), gsub("D", sample(D, 1), gsub("F", sample(F, 1), x)))))}))

Это работает довольно хорошо, но проблема в том, что если в столбце есть "A" (или любая другая буква), то этот A в этом конкретном столбце заменяется случайным числом из vector A, которое совпадает с по всей колонке.

Для иллюстрации:

Текущий фрейм данных (пока игнорируем NA)

Student_ID       ABC1000_Grade   ABC1003_Grade 
1    9000006           A              B          
2    9000014           A              A          
3    9000028           B              C          
4    9000045          <NA>           <NA>          
5    9000080           C             <NA>          
6    9000091          <NA>           <NA> 

Проблема:

Student_ID       ABC1000_Grade   ABC1003_Grade 
1    9000006        9.335523      8.231295          
2    9000014        9.335523      9.462468          
3    9000028        7.972959      6.394259          
4    9000045          <NA>           <NA>          
5    9000080        6.257297         <NA>          
6    9000091          <NA>           <NA> 

В столбце ABC1000_Grade символ A был заменен тем же случайным числом, которое было сгенерировано на предыдущем шаге.

Как я могу убедиться, что все замененные значения являются разными случайными числами? Таким образом, предпочтительный результат должен быть:

Student_ID       ABC1000_Grade   ABC1003_Grade 
1    9000006        9.510445      8.231295          
2    9000014        9.335523      9.462468          
3    9000028        7.972959      6.394259          
4    9000045          <NA>           <NA>          
5    9000080        6.257297         <NA>          
6    9000091          <NA>           <NA> 

Ответы [ 2 ]

3 голосов
/ 15 июня 2019

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

Вот более простой способ получить желаемый результат, используя base::switch() с sapply и, наконец, dplyr, чтобы изменить все столбцы, заканчивающиеся на "Grade" за один раз -

library(dplyr)

replace_grade <- function(g) {
  sapply(g, function(a) {
    switch(a,
         "A" = rnorm(1, 9.45, 0.2),
         "B" = rnorm(1, 7.95, 0.2),
         "C" = rnorm(1, 6.25, 0.2),
         "D" = rnorm(1, 4.75, 0.2),
         "F" = rnorm(1, 2, 0.2),
         NA_real_
         )
  })
}

# function output for illustration
replace_grade(g = c("A", "B", "C", "D", "F", NA_character_))
       A        B        C        D        F     <NA> 
9.229176 7.830536 6.239904 4.643644 2.146621       NA 

# apply function to every column ending with "Grade"
df %>% 
  mutate_at(vars(ends_with("Grade")), replace_grade)

  Student_ID ABC1000_Grade ABC1003_Grade
1    9000006      9.243239      7.946469
2    9000014      9.623083      9.072896
3    9000028      8.308868      6.177990
4    9000045            NA            NA
5    9000080      6.336819            NA
6    9000091            NA            NA

Данные -

df <- read.table(text = "Student_ID ABC1000_Grade   ABC1003_Grade
9000006 A   B
9000014 A   A
9000028 B   C
9000045 <NA>    <NA>
9000080 C   <NA>
9000091 <NA>    <NA>
", header= T, sep = "\t", stringsAsFactors = F)
0 голосов
/ 15 июня 2019

Базовая версия R, в которой мы создаем именованный список с возможными значениями в каждом классе и извлекаем одну случайную переменную на основе значения в столбце.

Student_Data[-1] <- sapply(unlist(Student_Data[-1]), 
                    function(x) if (is.na(x)) NA else sample(lst[[x]], 1))

Student_Data
#  Student_ID ABC1000_Grade ABC1003_Grade
#1    9000006      9.847739      7.689222
#2    9000014      9.605831      9.689179
#3    9000028      7.658435      6.244390
#4    9000045            NA            NA
#5    9000080      6.116549            NA
#6    9000091            NA            NA

Убедитесь, что оценки хранятся в виде символов, а не факторов.

, где lst -

lst <- list(A = rnorm(nrow(Student_Data), 9.45, 0.2), 
            B = rnorm(nrow(Student_Data), 7.95, 0.2), 
            C = rnorm(nrow(Student_Data), 6.25, 0.2), 
            D = rnorm(nrow(Student_Data), 4.75, 0.2), 
            F = rnorm(nrow(Student_Data), 2, 0.2))
...