2014-09-25 43 views
4

我想在apply內使用ifelse聲明,並得到一個奇怪的結果。如果變量是1,我會得到預期的答案,但當變量爲> 9時,則不會。ifelse聲明裏面申請返回意外的結果

下面是一個例子的數據集用於我得到正確的答案:

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在第二行中替換爲BBnewstage

+2

不知道這是否是問題,但如果你看看'申請(my.data2,1,函數( x)x)'由於標記列中的兩位數字14,標記列有兩個字符而不是一個字符。這會在你的代碼中產生「0」== 0,這是'FALSE'。但是,'「0」== 0'是'TRUE' – 2014-09-25 17:08:47

+2

爲什麼你不能使用'with(my.data,ifelse(status =='aaa'&stage =='NONE'&!marker&cumulative> 0 ,'BB',stage))' – akrun 2014-09-25 17:17:15

回答

4

如果你看一下apply(my.data2, 1, function(x) x),該列有兩個字符,而不是一個。這是因爲兩位數字14。對字符的強制將空格填充到列的最長(大多數字符)元素的長度。這會在您的代碼中生成" 0" == 0,即FALSE。但是,"0" == 0TRUE

" 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 2014-09-25 17:27:10

+0

非常好。我應該知道這一點。 – 2014-09-25 17:27:41

3

因此,當您使用apply時,該函數會將my.data轉換爲字符矩陣。當這種情況發生時,正如Richard Scriven在評論中指出的那樣,您最後會看到列中有額外的空間。當您運行比較時,numeric s會轉換爲character s,並且沒有此額外空間,因此請返回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'。 – 2014-09-25 17:21:30