2016-11-12 33 views
1

我繼承了一些遺留的R代碼來處理該代碼,該代碼基於同一行中的某個其他列中的值重新編碼列中的某些值這被誤認爲是時,在現實中,這些值實際上是(字符串轉換爲)的因素,像這樣一個布爾值:R:意外地使用因子列對數據框進行子集化,就好像它是邏輯的一樣

df <- data.frame(value = c(1, 2, 3, 4, 5, 6), 
       reversed = c("true", "false", 
           "true", "true", 
           "false", "false")) 

str(df) 
#> 'data.frame': 6 obs. of 2 variables: 
#> $ value : num 1 2 3 4 5 6 
#> $ reversed: Factor w/ 2 levels "false","true": 2 1 2 2 1 1 

df$recoded_value <- df$value 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 

如果檢查的結果,這將產生意外的結果。 df[2, "recoded_value"]是5,但意圖是它是2.此外,df[3, "recoded_value"]是3,但意圖是它爲4.

我想了解這裏發生了什麼。我的第一個假設是R將一個因子水平作爲TRUE,另一個作爲FALSE。但是,這顯然並非如此,因爲相同的因素水平被同等對待:

df[c(1,3), ] 
#> value reversed recoded_value 
#> 1  1  true    6 
#> 3  3  true    3 

df[c(2,5), ] 
#> value reversed recoded_value 
#> 2  2 false    5 
#> 5  5 false    5 

這到底是怎麼回事?

澄清:我對問題的解決方案不感興趣。我知道如何修復代碼以產生預期的結果。我想了解:

  1. 爲什麼此代碼可以工作?你如何基於因子列進行子集劃分?什麼是`[`甚至允許這樣做?
  2. 爲什麼相同價值的東西(,即,相同水平的因素)被區別對待?

回答

1

由於它是在後提到的,reversedfactor而不是logical矢量。在RTRUE/FALSE值邏輯,所以轉換爲logical矢量

df$reversed <- df$reversed=="true" 

至於爲什麼我們會有意想不到的輸出(來自OP的代碼),

df$reversed 
#[1] true false true true false false 
#Levels: false true 

levels都按字母順序並且factor的存儲模式是integer

as.integer(df$reversed) 
#[1] 2 1 2 2 1 1 

所以,當我們子集「recoded_value」使用「逆轉」,它將子集基礎上的數字指標

df$recoded_value[df$reversed] 
#[1] 2 1 2 2 1 1 

即在輸出的第一個值是「recoded_value」和第二一號的第二觀察觀察等,而是如果我們用正確的邏輯索引

df$recoded_value[df$reversed=="true"] 
#[1] 1 3 4 

讓我們來看看如何將與改變「逆轉」的行爲

df$reversed <- df$reversed=="true" 
df$recoded_value[df$reversed] <- 7 - df$recoded_value[df$reversed] 
df[c(1,3), ] 
# value reversed recoded_value 
#1  1  TRUE    6 
#3  3  TRUE    4 
df[c(2,5),] 
# value reversed recoded_value 
#2  2 FALSE    2 
#5  5 FALSE    5 
+1

感謝您的回答!不知道爲什麼我以前沒有意識到這一點。我認爲在構建最簡單的例子時我選擇了糟糕的數字;我不應該選擇與行號相同的值。 ':-p'無論如何,謝謝。 +1 –

相關問題