2014-09-22 66 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