#r #if-statement #error-handling
Вопрос:
Мой набор данных содержит следующие опечатки
unique(d$gender)
[1] "k" "kobieta" "M" "K" "m─Ö┼╝czyzna" "21" "m" "M─Ö┼╝czyzna"
> unique(d$age)
[1] 19 NA 21 20 30 32 22 25 29
На самом деле, строки с 21 для пола и NA для возраста были изменены, и более того, для переменной пола использовались разные названия (действительно, все название заголовка » к «соответствует женской «Ф», а заголовок с » м «означает мужскую «М»). Я записал эти командные строки, чтобы исправить это для переменной пола:
> d$gender = ifelse(d$gender == 'K', 'F',
ifelse(d$gender =='kobieta', 'F', ifelse(d$gender == 'k', 'F',
ifelse(d$gender == "m-Ö czyzna", 'M',ifelse(d$gender == '21', 'M',
ifelse(d$gender == 'm', 'M', ifelse(d$gender == 'M-Ö czyzna', 'M',
ifelse(d$gender == 'M', 'M', 'M'))))))))
>
> unique(d$gender)
[1] "F" "M"
Но я не знаю, как сделать то же самое для переменной возраста, и не знаю, может ли этот метод быть правильным. У кого-нибудь есть какие-нибудь предложения?
Это результат dput() :
dput(head(d,50))
structure(list(ID = c("P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323", "P1323", "P1323", "P1323", "P1323",
"P1323", "P1323", "P1323"), gender = c("F", "F", "F", "F", "F",
"F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F",
"F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F",
"F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F", "F",
"F", "F", "F", "F", "F", "F"), age = c(19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19), fixation_time = c(60,
60, 60, 60, 60, 70, 50, 50, 50, 70, 70, 60, 50, 60, 70, 70, 50,
70, 70, 60, 70, 50, 50, 50, 60, 70, 60, 50, 60, 70, 60, 70, 50,
60, 70, 50, 50, 70, 70, 70, 70, 50, 60, 50, 60, 60, 70, 50, 60,
60), block = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor"),
t1.key = c("None", "None", "None", "space", "None", "space",
"None", "None", "None", "space", "None", "None", "space",
"None", "None", "space", "None", "None", "space", "None",
"space", "space", "space", "None", "None", "None", "space",
"space", "None", "None", "space", "None", "None", "None",
"None", "None", "None", "space", "space", "None", "None",
"None", "None", "space", "None", "None", "space", "None",
"space", "None"), T1.response = structure(c(1L, 1L, 1L, 2L,
1L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L,
1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 1L,
1L, 1L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L,
1L), .Label = c("0", "1"), class = "factor"), COND = c("NR",
"NR", "NR", "R", "NR", "R", "NR", "NR", "NR", "R", "NR",
"NR", "R", "NR", "NR", "R", "NR", "NR", "R", "NR", "R", "R",
"R", "NR", "NR", "NR", "R", "R", "NR", "NR", "R", "NR", "NR",
"NR", "NR", "NR", "NR", "R", "R", "NR", "NR", "NR", "NR",
"R", "NR", "NR", "R", "NR", "R", "NR"), T1.rt = c(NA, NA,
NA, 0.812299799988978, NA, 0.72336569998879, NA, NA, NA,
0.772733500052709, NA, NA, 0.606754800013732, NA, NA, 0.601030899968464,
NA, NA, 0.838272600027267, NA, 0.305548300035298, 0.849945599969942,
0.748269900039304, NA, NA, NA, 0.859215400007088, 0.95704890001798,
NA, NA, 0.874362500035204, NA, NA, NA, NA, NA, NA, 0.270455699996091,
0.75726039998699, NA, NA, NA, NA, 0.762694000033662, NA,
NA, 0.789715700026136, NA, 0.90579859999707, NA), CR.key = c("p",
"p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p",
"p", "o", "p", "i", "i", "h", "u", "i", "u", "o", "o", "p",
"p", "p", "o", "p", "i", "o", "p", "p", "p", "o", "o", "o",
"p", "i", "p", "p", "o", "o", "i", "i", "o", "o", "i", "i",
"u"), CR.rt = c(0.651771800010465, 0.585048799985088, 0.652350199990906,
0.69888829998672, 1.01917029998731, 0.550036200031173, 0.0361186999944039,
0.568817299965303, 0.452191599993966, 0.514980700041633,
0.619590600021184, 0.719264700019266, 0.466181399999186,
0.45217840000987, 0.668881699966732, 0.914478300022893, 1.01910460001091,
1.40315000002738, 1.69993370003067, 1.71914210001705, 1.29938790004235,
0.698139799991623, 0.848338100011461, 0.651829700043891,
0.486136299965438, 0.703567499993369, 0.76673849998042, 0.54929809999885,
0.718664799991529, 0.768383099988569, 0.898415500007104,
0.819344500021543, 0.61898209998617, 0.737225699995179, 1.03654629999073,
0.971092400024645, 1.4362695000018, 0.999490200018045, 0.932840399967972,
0.586312200000975, 0.786785800009966, 1.01987839996582, 0.93673920002766,
0.715710600023158, 0.819960499997251, 0.75370900001144, 0.818668299994897,
0.903600800025742, 1.1176545000053, 1.10352450003847), trial_num = c(0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51,
52, 53), ldots = c(48, 48, 52, 55, 51, 51, 52, 49, 45, 55,
49, 49, 51, 49, 48, 52, 45, 49, 45, 55, 51, 48, 55, 51, 45,
45, 52, 48, 48, 48, 55, 51, 49, 48, 49, 51, 51, 55, 51, 49,
45, 55, 51, 55, 55, 52, 52, 48, 49, 52), rdots = c(52, 52,
48, 45, 49, 49, 48, 51, 55, 45, 51, 51, 49, 51, 52, 48, 55,
51, 55, 45, 49, 52, 45, 49, 55, 55, 48, 52, 52, 52, 45, 49,
51, 52, 51, 49, 49, 45, 49, 51, 55, 45, 49, 45, 45, 48, 48,
52, 51, 48), TASK = c("left", "left", "left", "left", "left",
"left", "left", "left", "left", "left", "left", "left", "left",
"left", "left", "left", "left", "left", "left", "left", "left",
"left", "left", "left", "left", "left", "left", "left", "left",
"left", "left", "left", "left", "left", "left", "left", "left",
"left", "left", "left", "left", "left", "left", "left", "left",
"left", "left", "left", "left", "left"), T1.correct = structure(c(1L,
1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 2L,
1L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L,
2L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,
2L, 1L, 1L, 2L), .Label = c("0", "1"), class = "factor"),
Go.Nogo..whether.a.person.should.respond. = c("NR", "NR",
"R", "R", "R", "R", "R", "NR", "NR", "R", "NR", "NR", "R",
"NR", "NR", "R", "NR", "NR", "NR", "R", "R", "NR", "R", "R",
"NR", "NR", "R", "NR", "NR", "NR", "R", "R", "NR", "NR",
"NR", "R", "R", "R", "R", "NR", "NR", "R", "R", "R", "R",
"R", "R", "NR", "NR", "R"), T1.ACC = structure(c(2L, 2L,
1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 1L,
2L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 1L, 2L,
2L, 1L, 1L), .Label = c("0", "1"), class = "factor"), CR = structure(c(4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 3L, 4L,
2L, 2L, 5L, 1L, 2L, 1L, 3L, 3L, 4L, 4L, 4L, 3L, 4L, 2L, 3L,
4L, 4L, 4L, 3L, 3L, 3L, 4L, 2L, 4L, 4L, 3L, 3L, 2L, 2L, 3L,
3L, 2L, 2L, 1L), .Label = c("1", "2", "3", "4", "9"), class = "factor"),
difficulty = c("medium", "medium", "medium", "easy", "hard",
"hard", "medium", "hard", "easy", "easy", "hard", "hard",
"hard", "hard", "medium", "medium", "easy", "hard", "easy",
"easy", "hard", "medium", "easy", "hard", "easy", "easy",
"medium", "medium", "medium", "medium", "easy", "hard", "hard",
"medium", "hard", "hard", "hard", "easy", "hard", "hard",
"easy", "easy", "hard", "easy", "easy", "medium", "medium",
"medium", "hard", "medium")), row.names = c(NA, -50L), class = c("tbl_df",
"tbl", "data.frame"))
Комментарии:
1. Не могли бы вы предоставить образец ваших данных с
dput()
2. Также я не понимал, что не так с возрастом
3. Я просто не могу придумать конкретный метод замены if на 21 в столбце «Пол».
4. набор данных довольно большой. Я не могу собрать все наблюдения с помощью dput().
5. если у вас есть другой метод, я могу использовать его.
Ответ №1:
Я не знаю, в чем проблема с Возрастом. Но оператор ifelse может быть переписан следующим образом:
Если в поле нет аномалий d$gender
:
d$gender2 = ifelse(tolower(substr(d$gender,1,1)) == "k", "F", "M")
Если в d$gender
поле есть аномалии:
d$gender2 = ifelse(tolower(substr(d$gender,1,1)) == "k", "F",
ifelse(tolower(substr(d$gender,1,1)) == "m" | d$gender == "21", "M", "Other")
Я думаю, что это более удобный метод. и вы могли бы использовать некоторые варианты, подобные этому.
В случае с Возрастом я не знаю, что вы хотите делать.
Комментарии:
1. Абсолютно полезно. Большое спасибо, что очень помогли. Не могли бы вы коротко описать функцию tolower и то, что она делает? Еще раз спасибо.
2.
tolower()
делает каждый символ строчным строчным регистром.toupper()
переводит каждый символ из строки в верхний регистр. Попробуйте ознакомиться с написанием документации?tolower
. Рад вам помочь. Если вы удовлетворены моим ответом, вы можете озвучить его. Хорошего дня.
Ответ №2:
Я хотел бы познакомить вас с двумя вещами: %in%
оператором и datastep()
функцией.
%in%
Оператор позволяет объединить возможные совпадения в вектор. Так что вы можете сделать x %in% c(y, z)
вместо ifelse(x == y, a, ifelse(x == z, a, x))
этого . Это может значительно уменьшить количество вложенных условий.
Во-вторых, я написал пакет под названием libr, в котором есть функция datastep()
, которая была специально разработана для очистки данных, как вы пытаетесь сделать. Это подходит для ситуаций, когда у вас много вложенных условий и сложная логика. Он перебирает данные строка за строкой, позволяет просматривать значения в каждой строке и создавать новые значения на основе значений конкретной строки. Самое лучшее, что вы можете вложить условные обозначения так глубоко, как хотите, и все равно читать их.
Вот пример использования обоих %in%
и datastep()
функции:
library(libr)
# Sample data
d <- data.frame(gender = c("k", "kobieta", "M", "K", "m─Ö┼╝czyzna", "21", "m", "M─Ö┼╝czyzna", "F"),
age = c(19, NA, 21, 20, 30, 32, 22, 25, 29))
# Define datastep
d2 <- datastep(d, {
if (gender %in% c('K', 'k', 'kobieta', 'f')) {
gender_corrected <- 'F'
} else if (gender %in% c('m', 'm─Ö┼╝czyzna', 'M─Ö┼╝czyzna')) {
gender_corrected <- 'M'
} else if (gender == 21) {
gender_corrected <- 'M'
} else {
gender_corrected <- gender
}
if (is.na(age)) {
# Do something
} else {
if (age < 10) {
# Do something else
} else {
age_corrected <- age
}
}
})
Таким образом, результат d2 будет выглядеть следующим образом:
> d2
gender age age_corrected gender_corrected
1 k 19 19 F
2 kobieta NA NA F
3 M 21 21 M
4 K 20 20 F
5 m-Ö czyzna 30 30 M
6 21 32 32 M
7 m 22 22 M
8 M-Ö czyzna 25 25 M
9 F 29 29 F
Комментарии:
1. Это гениальная и полезная функция для запуска. Спасибо!! К тому же довольно полезно и поучительно.
2. Тем не менее, я попытался запустить его как есть, но после проверки результатов с помощью функции unique(d$gender), которая всегда возвращает одни и те же ошибки.
3. Исправленные роды указаны в d$gender_corrected. Я ожидал, что вы поймете, что происходит, и измените условия в соответствии с вашими потребностями.
4. Я обдумывал это, но на самом деле я не в состоянии разобраться в этой проблеме. Я продолжаю исправлять эту ошибку.