IF-оператор с несколькими условиями, всегда говорящий true (вложенный в цикл while) - PullRequest
1 голос
/ 23 марта 2019

Пожалуйста, смотрите мой код ниже.

У меня есть фрейм данных, в котором каждая раса, с которой человек идентифицирует себя, находится в столбце (например, AWHITE, ABLACK и т. Д.), И если они идентифицируются с этой расой, то запись равна 1 (если не запись равна 2). Респонденты могут идентифицировать себя с более чем одной расой.

Я пытаюсь определить, когда респондент заявил, что он принадлежит к нескольким расам. Если они это сделают, я хочу, чтобы один столбец (ARACE) обновился до 91, а другой столбец (AOTHRACE) стал 2.

Оператор if (в коде ниже) всегда имеет значение TRUE. Хотя это не правильно. Есть респонденты, которые идентифицируют себя только как одну расу (т.е. белые). Я смотрел это несколько раз, но я не могу найти, где я испортил.

Я планирую использовать больше выражений if (если, иначе if) и для других рас / столбцов (т. Е. Респондент идентифицирует как черных И, по крайней мере, еще одну расу), но я даже не могу получить первую работать, поэтому я не реализовал это.

(на самом деле я не хочу, чтобы else равнялся 0, я просто использовал это, чтобы подтвердить, что код не работает должным образом. Когда я запустил функцию сводки в ARACE, минимум составил 91, поэтому я знаю, что это утверждение было никогда не оценивался.)

i <- 0
while (i <= nrow(nhes05v2)){
  if ((nhes05v2$AWHITE == 1) && (any(nhes05v2$ABLACK==1, nhes05v2$AAMIND==1, nhes05v2$AASIAN==1, nhes05v2$APACI==1))){
    nhes05v2$ARACE = 91
    nhes05v2$AOTHRACE = 2}
  else {nhes05v2$ARACE = 0
  nhes05v2$AOTHRACE = 0}
  i <- i+1}

Вот пример значений:

> nhes05v2$AWHITE[1:20]
 [1] 1 1 1 1 1 1 2 2 2 1 1 2 1 1 1 1 1 1 1 1
> nhes05v2$ABLACK[1:20]
 [1] 2 1 2 2 2 2 1 1 1 2 2 1 2 2 2 2 2 2 2 2
> nhes05v2$AASIAN[1:20]
 [1] 2 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2
> nhes05v2$AAMIND[1:20]
 [1] 2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2
> nhes05v2$APACI[1:20]
 [1] 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2

Я бы хотел, чтобы результат был что-то вроде (это было бы больше, чем просто мой оператор if, приведенный выше, было бы больше if, else if, но так как я застрял на первом, у меня не было ' это уже прошло)

> nhes05v2$ARACE[1:20]
 [1] 0 91 0 91 0 91 91 0 0 91 0 0 0 0 0 0 0 0 0 0
> nhes05v2$AOTHRACE[1:20]
 [1] 0 2 0 2 0 2 2 0 0 2 0 0 0 0 0 0 0 0 0 0

В настоящее время вывод

> nhes05v2$ARACE[1:20]
 [1] 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91 91
> nhes05v2$AOTHRACE[1:20]
 [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

Ответы [ 2 ]

0 голосов
/ 23 марта 2019

Используя пакеты dplyr и magrittr, моя лучшая версия выглядит так:

nhes05v2 %>%
  mutate(ARACE = ifelse(AWHITE == 1 & (ABLACK == 1 | AAMIND ==1 | AASIAN == 1 | APACI == 1), 91, 0),
         AOTHRACE = ifelse(AWHITE == 1 & (ABLACK == 1 | AAMIND ==1 | AASIAN == 1 | APACI == 1), 2, 0))

Условие && в R проверяет только первую строку, поэтому вы получили результаты, которые вы здесь сделали - вот сообщение от других людей, которые были сбиты с толку этим поведением.

0 голосов
/ 23 марта 2019

Этого можно добиться, перекодировав 2 в 0 (т. Е. 0 = «Нет») и используя следующий код с двумя функциями, используемыми для определения того, удовлетворяет ли запись критериям.

Обратите внимание, что в коде предполагается, что переменные расы являются числовыми.

# Replicate your example
AWHITE = as.numeric(unlist(strsplit("1 1 1 1 1 1 2 2 2 1 1 2 1 1 1 1 1 1 1 1", " ")))
ABLACK = as.numeric(unlist(strsplit("2 1 2 2 2 2 1 1 1 2 2 1 2 2 2 2 2 2 2 2", " ")))
AASIAN = as.numeric(unlist(strsplit("2 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2", " ")))
AAMIND = as.numeric(unlist(strsplit("2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2", " ")))
APACI = as.numeric(unlist(strsplit("2 2 2 2 2 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2", " ")))

nhes05v2 = data.frame(AWHITE, ABLACK, AASIAN, AAMIND, APACI)
> nhes05v2  # Partial output given
   AWHITE ABLACK AASIAN AAMIND APACI
1       1      2      2      2     2
2       1      1      2      2     2
3       1      2      2      2     2
...
18      1      2      2      2     2
19      1      2      2      2     2
20      1      2      2      2     2

Перекодировать переменные

# Recode variables. Change all 2's to 0's (New coding is 1 = Yes, 0 = No).
nhes05v2[nhes05v2 == 2] = 0

Создание 2 функций для удовлетворения критериев ARACE и AORACE

# A person is mixed race it they answer 1 to more than one race
# Therefore a person whose row sum is greater than 1 is mixed race

determine.arace = function(AWHITE, ABLACK, AAMIND, AASIAN, APACI){
  ifelse( sum(AWHITE, ABLACK, AAMIND, AASIAN, APACI ) > 1 , 91, 0)
}

determine.aothrace = function(AWHITE, ABLACK, AAMIND, AASIAN, APACI){
  ifelse( sum(AWHITE, ABLACK, AAMIND, AASIAN, APACI ) > 1 , 2, 0)
}

Примените эти функции к вашим данным

ARACE = mapply(determine.arace, nhes05v2$AWHITE, nhes05v2$ABLACK, nhes05v2$AAMIND, nhes05v2$AASIAN, nhes05v2$APACI)
> ARACE
[1]  0 91  0 91  0 91 91  0  0  0  0  0  0 91  0  0  0  0  0  0

AOTHRACE = mapply(determine.aothrace, nhes05v2$AWHITE, nhes05v2$ABLACK, nhes05v2$AAMIND, nhes05v2$AASIAN, nhes05v2$APACI)
> AOTHRACE
[1] 0 2 0 2 0 2 2 0 0 0 0 0 0 2 0 0 0 0 0 0

Чтобы добавить их в ваш фрейм данных

nhes05v2$ARACE = ARACE
nhes05v2$AOTHRACE = AOTHRACE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...