2014-09-22 67 views
0

我想要droplevels數據框(請不要將此問題標記爲重複:))。 鑑於所有可用的方法只有一個可行。我究竟做錯了什麼? 實施例:R數據框因子

> df = data.frame(x = (c("a","b","c")),y=c("d","e","f")) 
> class(df$x) 
[1] "factor" 
> levels(df$x) 
[1] "a" "b" "c" 

方法1不工作:

> df1 = droplevels(df) 
> class(df1$x) 
[1] "factor" 
> levels(df1$x) 
[1] "a" "b" "c" 

方法2不工作:

> df2 = as.data.frame(df, stringsAsFactors = FALSE) 
> class(df2$x) 
[1] "factor" 
> levels(df2$x) 
[1] "a" "b" "c" 

方法3不工作:

> df3 = df 
> df3$x = factor(df3$x) 
> class(df3$x) 
[1] "factor" 
> levels(df3$x) 
[1] "a" "b" "c" 

方法4最後工作:

> df4 = df 
> df4$x = as.vector(df4$x) 
> class(df4$x) 
[1] "character" 
> levels(df4$x) 
NULL 

在工作時,我覺得方法4是最不優雅的。你能幫我調試嗎?非常感謝

編輯:以下意見和答案:我想從一個數據幀刪除因子結構,不僅droplevels

+4

所以,當你說你要'droplevels'你真的只是意味着你要的因子變量轉換爲字符varaible。如果是這樣,方法4是唯一系統正確的選擇。 'droplevels'從一個因素中刪除未觀察到的水平,但在您的測試案例中,您會觀察到所有水平,因此不會丟失任何東西。如果你不想讓它們成爲因素,可以使用'df = data.frame(x =(c(「a」,「b」,「c」)),y = c(「d」, 「e」,「f」),stringsAsFactors = FALSE)。方法2不起作用,因爲它們已經是當時的因素。什麼*確切*是你的目標? – MrFlick 2014-09-22 17:26:47

+0

@MrFlick,謝謝你的解釋,不過還是很奇怪,方法2不行的 – MasterJedi 2014-09-22 17:31:01

+0

@YujiaHu一點也不奇怪。如果你通過'as.data.frame',一個data.frame所做的就是調整class屬性和(可能)行名。 – joran 2014-09-22 17:34:19

回答

4

「降低水平」是指消除未使用的因子水平,但將對象保留爲類factor。您正在尋找一種方式來所有的因素列轉換爲字符列:

> df2 = data.frame(lapply(df, 
      function(x) if (is.factor(x)) as.character(x) else x), 
       stringsAsFactors = FALSE) 
> lapply(df2, class) 
$x 
[1] "character" 

$y 
[1] "character" 

> df2 
    x y 
1 a d 
2 b e 
3 c f 
4

我猜你想:

df[] <- lapply(df, as.character) 

這有兩個差異從您的代碼:保留df的數據幀結構和使用lapply的作業LHS上的「[]」。 droplevels函數只能刪除多餘的級別,但不會轉換爲字符向量。 as.character函數沒有data.frame方法。它需要(1)應用於每個因子矢量,而不是用於因子矢量列表。更普遍的功能,要做到這一點(避免試圖在數字矢量脅迫的誤差)是:

makefac2char <- function(v) if(is.factor(v)){as.character(v)} else {v} 
df[] <- lapply(df, makefac2char) 
# To make a new dataframe 
df2 <- lapply(df, makefac2char) 
df2<- data.frame(df2) 

如果你不想破壞性取代「東風」,那麼你需要環繞lapply結果data.frame因爲lapply不保留屬性。如果您使用'stringAsFactors = FALSE'創建了該數據框(或在.Options中設置了該選項),則不需要在數據框架範圍內完成此操作。

+1

標準的'droplevels()'似乎表現得很好,超過了data.frame'df = data.frame(x = factor(c(「a」,「b」,「c」),levels = letters),y = c(「d」,「e」,「f」),z = 1:3); droplevels(DF)'。不知道這是什麼實現。 – MrFlick 2014-09-22 17:32:36

+0

很確定'droplevels'確實有一個data.frame方法。 – joran 2014-09-22 17:32:49

+0

對不起。提問者對「水滴」的作用感到困惑(並且困惑於我)。編輯給他他想要的東西,但是使用錯誤的功能來實現。他希望'as.character'。 – 2014-09-22 17:37:29