2014-09-25 14 views
4

Я пытаюсь использовать оператор ifelse внутри apply и получаю нечетный результат. Я получаю ожидаемый ответ, если переменная равна 1, но не тогда, когда эта переменная равна > 9.ifelse statement in apply возвращает неожиданный результат

Ниже приведен пример набора данных, для которого я получаю правильный ответ:

my.data <- read.table(text = ' 
    REFNO status stage marker cumulative newstage 
1018567  ccc  AA  0    1   AA 
1018567  aaa  NONE  0    1  NONE 
1018567  aaa  BB  1    1   BB 
1018567  bbb  CC  1    1   CC 
1018567  eee  CC  1    1   CC 
1018567  mmm  CC  1    1   CC 
1018567  ppp  CC  1    1   CC 
1019711  ddd  CC  1    1   CC 
', header = TRUE, stringsAsFactors = FALSE) 

my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status'] == 'aaa' & 
              x['stage']  == 'NONE' & 
              x['marker']  == 0  & 
              x['cumulative'] > 0, 'BB', x['stage'])) 

my.data 

Набор данных ниже отличается только один элемент из этого выше, но я не получить правильный ответ.

my.data <- read.table(text = ' 
    REFNO status stage marker cumulative newstage 
1018567  ccc  AA  0    1   AA 
1018567  aaa  NONE  0    1  NONE 
1018567  aaa  BB  1    1   BB 
1018567  bbb  CC  1    1   CC 
1018567  eee  CC  1    1   CC 
1018567  mmm  CC  1    1   CC 
1018567  ppp  CC  1    1   CC 
1019711  ddd  CC  14    1   CC 
', header = TRUE, stringsAsFactors = FALSE) 

my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status'] == 'aaa' & 
              x['stage']  == 'NONE' & 
              x['marker']  == 0  & 
              x['cumulative'] > 0, 'BB', x['stage'])) 

my.data 

Благодарим за любые предложения. Возможно, я должен использовать инструкцию if вместо if-else?

В частности, я бы хотел, чтобы NONE был заменен на BB для newstage во втором ряду.

+2

Не уверен, если это проблема, но если вы посмотрите на 'применить (my.data2, 1, функция (x) x) 'Столбец маркера имеет два символа вместо одного из-за двух цифр 14 в столбце маркера. Это приводит к '' 0 "== 0' в вашем коде, что является' FALSE'. Однако '' 0 "== 0' является' TRUE' –

+2

Почему вы не можете использовать 'with (my.data, ifelse (status == 'aaa' & stage == 'NONE' &! Marker & cumulative> 0 , 'BB', stage)) ' – akrun

ответ

4

Если посмотреть на apply(my.data2, 1, function(x) x), то столбец имеет два символа вместо одного. Это связано с двумя цифрами 14. Принуждение к символу заполняет столбец пробелами до длины самого длинного (большинства символов) элемента. Это дает " 0" == 0 в вашем коде FALSE. Однако "0" == 0 является TRUE

" 0" == 0 
# [1] FALSE 
"0" == 0 
# [1] TRUE 

С ifelse является векторизация, вам не нужно использовать apply вообще. Вы можете добавить новый столбец с within (или with как akrun упоминает) или просто с newstage <- ifelse(...)

within(my.data2, { 
    newStage <- ifelse(status == "aaa" & stage == "NONE" & marker == 0 & 
          cumulative > 0, "BB", stage) 
}) 
#  REFNO status stage marker cumulative newstage newStage 
# 1 1018567 ccc AA  0   1  AA  AA 
# 2 1018567 aaa NONE  0   1  NONE  BB 
# 3 1018567 aaa BB  1   1  BB  BB 
# 4 1018567 bbb CC  1   1  CC  CC 
# 5 1018567 eee CC  1   1  CC  CC 
# 6 1018567 mmm CC  1   1  CC  CC 
# 7 1018567 ppp CC  1   1  CC  CC 
# 8 1019711 ddd CC  14   1  CC  CC 
+1

Да. Это намного лучше, чем практика кодирования в целом. – stanekam

+0

Отлично. Я должен был это знать. –

3

Поэтому, когда вы используете применение как есть, функция преобразует my.data в матрицу символов. Когда это произойдет, как указывает Ричард Скривен в комментариях, вы получите столбец с дополнительным сапфиром. Когда вы проводите сравнение, numeric s преобразуются в character с и не имеют дополнительного пространства и поэтому возвращают FALSE.

Преобразование в numeric в ваш apply исправит это.

my.data$newstage <- apply(my.data, 1, function(x) ifelse(x['status']  == 'aaa' & 
                 x['stage']  == 'NONE' & 
                 as.numeric(x['marker'])  == 0  & 
                 as.numeric(x['cumulative']) > 0, 'BB', x['stage'])) 
+0

Спасибо. Очень полезно. Я продолжаю забывать, что 'apply' преобразуется в' matrix'. –

Смежные вопросы