0

我想要droplevels一个数据框(请不要将此问题标记为重复:))。鉴于所有可用的方法,只有一种有效。我究竟做错了什么?例子:

> 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

2 回答 2

4

我猜你想要:

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

这与您的代码有两个不同之处:分配的 LHS 上的“[]”保留dflapply. 该droplevels函数仅删除无关级别,但不会转换为字符向量。该as.character函数没有 data.frame 方法。它需要 (l) 应用于每个因子向量而不是因子向量列表。更通用的功能(避免尝试对数字向量进行强制转换的错误)是:

 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)

如果您不想破坏性地替换“df”,那么您需要环绕data.frame结果lapply,因为lapply不维护属性。如果您使用 'stringAsFactors=FALSE' 创建了该数据框(或在 中设置该选项.Options),则您不需要在 data.frame 范围内执行此操作。

于 2014-09-22T17:30:28.063 回答
4

“降低级别”是指摆脱未使用的因子级别,但将对象保留为 class 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
于 2014-09-22T17:32:51.510 回答