2011-10-01 88 views
3

我使用這樣的事情來篩選我的數據幀:無法過濾數據框?

d1 = data.frame(data[data$ColA == "ColACat1" & data$ColB == "ColBCat2", ]) 

當我打印d1,它按預期工作。但是,當我鍵入d1 $ ColB時,它仍會打印原始數據框中的所有內容。

> print(d1) 
ColA  ColB 
----------------- 
ColACat1 ColBCat2 
ColACat1 ColBCat2 

> print(d1$ColA) 
Levels: ColACat1 ColACat2 

也許這是預期,但是當我通過d1到ggplot,它攪亂了我的圖形,並且不使用過濾器。是否有反正我可以過濾數據幀,並得到只有匹配過濾器的記錄?我想d1不知道data的存在。

回答

5

正如你所暗示的,R中的默認行爲是將數據幀中的字符列視爲特殊數據類型,稱爲factor。這是一個功能,而不是一個錯誤,但是如果你不期待它並且不知道如何正確使用它,那麼它就像任何有用的功能一樣,這可能會讓人感到困惑。

factors旨在表示分類(而不是數字或定量)變量,這些變量經常出現在統計數據中。

您使用的子集操作實際上正常工作。也就是說,他們會返回數據框的正確子集。但是,該變量的levels屬性保持不變,並且仍具有全部其中的原始級別。

這意味着用R編寫的任何方法都是爲了利用factors而將該列視爲具有一堆關卡的分類變量,其中許多關鍵字不存在。在統計數據中,人們通常希望追蹤「缺失」的分類變量水平。

我其實更喜歡與stringsAsFactors = FALSE一起工作,但很多人對此表示不滿,因爲它可以減少代碼的可移植性。 (TRUE是默認設置,因此與其他人分享您的代碼可能會有風險,除非您以options的電話號碼爲每個腳本添加前綴)。

一種可能更方便的解決方案,特別是用於數據幀,是結合subsetdroplevels功能:

subsetDrop <- function(...){ 
    droplevels(subset(...)) 
} 

並使用該函數來提取數據幀的子集在被保證以除去一種方式結果中任何未使用的級別。

+0

+1非常感謝你的解釋。我不明白的是,爲什麼ggplot最終使用了不存在的級別。可能是他們有自己的理由。我在R和ggplot中都是一個完整的初學者,所以我最終花了一個多小時的時間試圖瞭解發生了什麼:) – Legend

+1

考慮因素水平的處理(即保留它們,儘管缺少數據),例如在分面時數據世界中的'正常',但它使大多數其他人失去知覺。理由是,如果缺少某些東西,你希望明確地顯示它缺失,例如通過顯示一個沒有數據的方面。 – joran

2

這真是太痛苦了!如果你沒有這樣做,ggplot會搞砸。使用此選項在我的腳本開始解決它:

options(stringsAsFactors = FALSE) 

看起來它是預期的行爲,但不幸的是我已經開啓此功能用於其他目的,並開始造成麻煩,我的所有其他腳本。

+0

這將解決您的問題,但默認的全局設置是stringsAsFactors = TRUE。當你構造data.frame(...,stringsAsFactors = FALSE)時,你也可以將它作爲參數傳遞。但在你的例子中,當你構造最初的'數據'data.frame時,必須完成這個工作。 –