【问题标题】:how do I remove one factor level in R?如何删除 R 中的一个因子水平?
【发布时间】:2015-08-30 20:42:36
【问题描述】:

我需要从 R 中的数据框中删除变量。我的数据有一列包含 18 个因子:

  1. 农业
  2. 渔业 ...
  3. 未分类

在创建虚拟变量之前,我需要删除因子 #18 来表示“X 人在 Y 行业工作”。也就是说,我只需要保留前 17 个级别(分类级别)

在Stata中删除级别将是

drop if rama1 == 99

(rama1 是因子列,99 是“未分类”)

然后在 Stata 中创建虚拟变量(每个行业一个二进制变量),我运行:

quietly tabulate rama1, generate(rama1_)

在 R 中是:

for(i in unique(data$rama1)) {
data[paste("type", i, sep="")] <- ifelse(data$rama1 == i, 1, 0)
}

有什么想法吗?非常欢迎您的帮助

【问题讨论】:

  • 欢迎来到 SO。首先你应该阅读here关于如何提出一个好问题;一个好的问题有更好的变化需要解决,你会得到帮助。另一方面,阅读this 也不错。它解释了如何在 R 中创建一个可重现的示例。帮助用户通过为您的数据提供所需的输出以及您迄今为止尝试过的事情来帮助您。
  • 为什么不只是data&lt;-data[rama1!="unclassified"]...
  • 我试过了,但什么也没做:S
  • 删除具有给定因子级别的所有元素不会删除该级别,您必须再次使用factor(...) 来执行此操作。
  • 如何调整数据

标签: r stata


【解决方案1】:

要移除关卡,BondedDust 或 jlhoward 采用的任何一种方式都可以正常工作。要创建虚拟变量,这将取决于您想要什么/您希望它如何制定。

例如,对于已删除的因子,您希望行显示为&lt;NA&gt; 还是0


基础R

最简单的方法是在基础 R 中使用 model.matrix。因此以 BondedDust 的示例为基础;

df <- data.frame(x=as.factor(sample(LETTERS[1:5],100, replace=TRUE)), y=1:100)

# remove E and the level
is.na(df$x) <- df$x == "E"
df$x <- factor(df$x)

产生这个:

> head(df)
     x y
1    D 1
2    C 2
3    A 3
4 <NA> 4
5    D 5
6    A 6

然后,我们可以简单地运行 model.matrix 来获取我们因子水平的虚拟变量。默认情况下,它会将所有 NA 更改为 0。

> model.matrix(~x, df)
    (Intercept) xB xC xD
1             1  0  0  1
2             1  0  1  0
3             1  0  0  0
5             1  0  0  1
6             1  0  0  0
8             1  1  0  0
9             1  0  0  0
11            1  0  0  0
12            1  0  1  0

插入符号

另一种方法是使用 caret 包,它可以在跨测试/保持模型运行这些因素/重新平衡时为您提供更多功能。

它包含为您执行此操作的 dummyVars 函数。

> xx <- dummyVars(~x, df)
> predict(xx, df)
    x.A x.B x.C x.D
1     0   0   0   1
2     0   0   1   0
3     1   0   0   0
4    NA  NA  NA  NA
5     0   0   0   1
6     1   0   0   0
7    NA  NA  NA  NA

【讨论】:

    【解决方案2】:

    R 还有一个“降低”关卡的功能,毫不奇怪地命名为droplevels。从上下文来看,我猜测 Stata 的 drop 更像 R 的 is.na&lt;-,因为它似乎将项目设置为在列中丢失。为了防止 R 显示现在“缺失”的关卡,您需要先删除这些值,然后再删除关卡。

    创建多个列,每个“虚拟”列是完全没有必要的。我怀疑Stata也不需要它。我认为这是一种可以从 SAS 或 SPSS 继承的操作。 R 中的回归和表操作将使用单个列适当地完成。

    df <- data.frame(x=as.factor(sample(LETTERS[1:5],100, replace=TRUE)), y=1:100)
    levels(df$x)
    #[1] "A" "B" "C" "D" "E"
    is.na(df$x) <- df$x == "E"
    lm( y~x, df)
    #--------------
    Call:
    lm(formula = y ~ x, data = df)
    
    Coefficients:
    (Intercept)           xB           xC           xD  
        49.3846      -0.7846       2.9838       2.7692  
    

    如果df1$rami 是通过对99 进行测试所建议的数字,那么它无论如何都不是一个因素,并且对级别的讨论没有密切关系。

    【讨论】:

    • Stata 的drop 从内存中的数据集中删除观察值或变量;它没有设置为丢失。更有趣的是,在这种情况下,Stata 具有避免创建新变量的机制,这是完全正确的;它被称为因子变量表示法。
    【解决方案3】:

    扩展我的评论:

    set.seed(1)
    df <- data.frame(x=as.factor(sample(LETTERS[1:5],10, replace=TRUE)), y=1:10)
    levels(df$x)
    # [1] "A" "B" "C" "D" "E"
    df <- df[df$x!="E",]        # remove all rows with df$x=="E"
    levels(df$x)                # level E remains
    # [1] "A" "B" "C" "D" "E"
    df$x <- factor(df$x)        # get rid of it...
    levels(df$x)
    # [1] "A" "B" "C" "D"
    

    请注意,as.factor(...) 不会起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-11-23
      相关资源
      最近更新 更多