有条件地更改数据框中的分类调查响应列的值

时间:2018-11-30 13:00:40

标签: r object

试图创建一个将某些类别合并到一个变量中的对象

background <- NULL

data$y11[data$y11 == "English/Welsh/Scottish/Northern Irish/British"] <-"White"

data$y11[data$y11 == "Gypsy or Irish Traveller"] <-"White"

data$y11[data$y11 == "Any other White background, please describe"] <-"White"

data$y11[data$y11 == "Irish"] <-"White"

data$y11[data$y11 == "Any other Mixed/Multiple ethnic background, please describe"] <-"Mixed"

data$y11[data$y11 == "White and Asian "] <-"Mixed"

data$y11[data$y11 == "White and Black African "] <-"Mixed"

data$y11[data$y11 == "White and Black Caribbean"] <-"Mixed"

data$y11[data$y11 == "Any other Asian background, please describe"] <-"Asian"

data$y11[data$y11 == "Bangladeshi"] <-"Asian"

data$y11[data$y11 == "Chinese"] <-"Asian"

data$y11[data$y11 == "Indian"] <-"Asian"

data$y11[data$y11 == "Pakistani"] <-"Asian"

data$y11[data$y11 == "Arab"] <-"Arab & Other"

data$y11[data$y11 == "Any other ethnic group, please describ"] <-"Arab & Other"

data$y11[data$y11 == "African"] <-"Black"

data$y11[data$y11 == "Any other Black/African/Caribbean background, please describe"] <-"Black"

data$y11[data$y11 == "Caribbean"] <-"Black"

但我保留有关“无效因子水平,NA产生”的警告消息

请帮助!

2 个答案:

答案 0 :(得分:1)

这意味着您的变量是因素。您可以通过以下两种方法之一解决此问题:

  1. 使用以下命令将所有因子更改为字符:

    data$y11 <- as.character(data$y11)

  2. 使用以下命令将所需的新级别添加到现有因子级别:

    levels(data$y11) <- c(levels(data$y11), "White", "Black", ...)

让我知道这是否没有道理

此外,以防万一您不熟悉R,也不需要像这样分散所有行。您可以将各个种族分组在一起,就像这样:

 data$y11[data$y11 %in% c("English/Welsh/Scottish/Northern Irish/British",
                          "Gypsy or Irish Traveller",
                          "Any other White background, please describe",
                          "Irish")] <-"White"

 data$y11[data$y11 %in% c("Any other Mixed/Multiple ethnic background, please describe",
                          "White and Asian ",
                          "White and Black African ",
                          "White and Black Caribbean")] <-"Mixed"

 data$y11[data$y11 %in% c("Any other Asian background, please describe",
                          "Bangladeshi",
                          "Chinese",
                          "Indian",
                          "Pakistani")] <-"Asian"

 data$y11[data$y11 %in% c("Arab",
                          "Any other ethnic group, please describ")] <-"Arab & Other"

 data$y11[data$y11 %in% c("African",
                          "Any other Black/African/Caribbean background, please describe",
                          "Caribbean"] <-"Black"

或者还有很多其他方法,例如使用|(或)运算符,因此您不必单独写出每一行。

答案 1 :(得分:1)

您的主要问题是,在读入数据时您未使用stringsAsFactors = FALSE(可能使用read.csv)。因此,您应该将其添加到read.csv调用中。

还有一种更好的方式来做您正在做的事情。一种方法是从一个类别创建到另一个类别的“查找”或“翻译”表,然后使用基数R中的merge或“ tidyverse”中的left_join自动为您替换完成所有这些条件分配。

我们将制作翻译表:

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

现在我们将模拟一些数据(我使用datdata作为变量名,因为使用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" ...

我们还可以使用“ tidyverse”中的dplyr

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会话中已经拥有的东西。

现在我们可以做到:

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" ...

我们将转换后的值作为字符向量而不是因子来获取。