У меня есть фрейм данных, который включает в себя оценки студентов за курс. Эти оценки, однако, представлены в формате AF и должны быть преобразованы в числовые оценки (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>





В вашем коде вы генерируете одно случайное значение для замены любой заданной оценки, и поэтому вы получаете одинаковые значения.
Вот более простой способ получить желаемый результат, используя base::switch() с sapply и, наконец, пакет dplyr для изменения всех столбцов, заканчивающихся на «Оценка», за один раз —
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)
Спасибо! switch() иногда может быть очень кстати.
Базовая версия 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))
Блестяще!! Я здесь использую
nested ifи забыл оswitch