Ваша основная проблема в том, что вы не использовали stringsAsFactors = FALSE
при чтении ваших данных (вероятно, с read.csv
).Поэтому вы должны добавить это к вызову read.csv
.
Существует также лучший способ сделать то, что вы делаете.Один из подходов заключается в создании таблицы «поиска» или «перевода» из одной категории в другую, а затем с помощью merge
из базы R или left_join
из «tidyverse» для автоматической замены для вас, не имея всех этих условныхприсваивания.
Мы создадим таблицу перевода:
data.frame(
answer = c(
"African", "Any other Asian background, please describe",
"Any other Black/African/Caribbean background, please describe",
"Any other ethnic group, please describ",
"Any other Mixed/Multiple ethnic background, please describe",
"Any other White background, please describe", "Arab", "Bangladeshi",
"Caribbean", "Chinese", "English/Welsh/Scottish/Northern Irish/British",
"Gypsy or Irish Traveller", "Indian", "Irish", "Pakistani", "White and Asian ",
"White and Black African ", "White and Black Caribbean"
),
subst = c(
"Black", "Asian", "Black", "Arab & Other", "Mixed", "White",
"Arab & Other", "Asian", "Black", "Asian", "White", "White", "Asian",
"White", "Asian", "Mixed", "Mixed", "Mixed"
),
stringsAsFactors = FALSE
) -> trans_tbl
Теперь мы смоделируем некоторые данные (я использую dat
против data
в качестве имени переменной с момента использованияdata
в конце концов вызовет у вас боль, так как это имя функции R):
set.seed(2018-11-30)
data.frame(
y11 = sample(trans_tbl$answer, 100, replace = TRUE),
stringsAsFactors = FALSE
) -> dat
str(dat)
## 'data.frame': 100 obs. of 1 variable:
## $ y11: chr "Caribbean" "Chinese" "Indian" "Any other Black/African/Caribbean background, please describe" ...
Ваш фрейм данных содержит более одного столбца, но вы его нам не показывали, поэтому я просто сделал одинфрейм данных столбцов с y11
.Теперь мы просто вызываем merge
:
dat <- merge(dat, trans_tbl, by.x="y11", by.y="answer", all.x=TRUE)
str(dat)
## 'data.frame': 100 obs. of 2 variables:
## $ y11 : chr "African" "African" "African" "African" ...
## $ subst: chr "Black" "Black" "Black" "Black" ...
и затем выполняем некоторые основные операции, чтобы преобразовать столбец subst
в y11
, как это делает ваш код:
dat$y11 <- dat$subst
dat$subst <- NULL
str(dat)
## 'data.frame': 100 obs. of 1 variable:
## $ y11: chr "Black" "Black" "Black" "Black" ...
Мы также можем использовать dplyr
из «tidyverse»:
library(tidyverse)
set.seed(2018-11-30)
data_frame( # this is the `data_frame()` function from dplyr, NOT `data.frame()` from base R
y11 = sample(trans_tbl$answer, 100, replace = TRUE)
) -> dat
left_join(dat, trans_tbl, by = c("y11"="answer")) %>%
select(y11 = subst)
## # A tibble: 100 x 1
## y11
## <chr>
## 1 Black
## 2 Asian
## 3 Asian
## 4 Black
## 5 Asian
## 6 Mixed
## 7 Arab & Other
## 8 Asian
## 9 Arab & Other
## 10 Asian
## # ... with 90 more rows
Другой метод заключается в использовании факторных операций.
Мы будем использовать тот же код для создания симулированного фрейма данных:
possible_answers <- c(
"African", "Any other Asian background, please describe",
"Any other Black/African/Caribbean background, please describe",
"Any other ethnic group, please describ",
"Any other Mixed/Multiple ethnic background, please describe",
"Any other White background, please describe", "Arab", "Bangladeshi",
"Caribbean", "Chinese", "English/Welsh/Scottish/Northern Irish/British",
"Gypsy or Irish Traveller", "Indian", "Irish", "Pakistani", "White and Asian ",
"White and Black African ", "White and Black Caribbean"
)
what_they_should_be <- c(
"Black", "Asian", "Black", "Arab & Other", "Mixed", "White",
"Arab & Other", "Asian", "Black", "Asian", "White", "White", "Asian",
"White", "Asian", "Mixed", "Mixed", "Mixed"
)
set.seed(2018-11-30)
data.frame(
y11 = sample(possible_answers, 100, replace = TRUE)
) -> dat
Обратите внимание, что я не использовал stringsAsFactors = FALSE
для этого, что делает его более похожим на то, что у вас уже есть в вашем сеансе R.
Теперь мы можемdo:
dat$y11 <- as.character(factor(
x = dat$y11,
levels = possible_answers,
labels = what_they_should_be
))
str(dat)
## 'data.frame': 100 obs. of 1 variable:
## $ y11: chr "Black" "Asian" "Asian" "Black" ...
И мы получаем переведенные значения как символьный вектор, а не как фактор.