【问题标题】:Why are my factor levels turning to numbers with dplyr::mutate()?为什么我的因子水平使用 dplyr::mutate() 变为数字?
【发布时间】:2017-06-23 20:02:05
【问题描述】:

我正在尝试使用 dplyr::mutate() 重新编码一些因子水平,以便所有“MOT”和“CHI”因子水平保持原样,而所有其他因子水平都转向“OTH”。

我的数据如下所示:

subj | speaker | word

1        MOT     apple
1        CHI     baby
1        SI1     baby
2        CHI     dog
2        CHI     cat
2        FAT     cat

我希望它看起来像这样:

subj | speaker | word

1        MOT     apple
1        CHI     baby
1        OTH     baby
2        CHI     dog
2        CHI     cat
2        OTH     cat

我的代码如下所示:

new.df <- data %>%
  dplyr::select(subj, speaker) %>%
        mutate(speaker = factor(speaker),
         speaker = ifelse(speaker %in% c("CHI", "MOT"), speaker, "OTH")) 

但是,当我运行此脚本时,某些级别会转换为“OTH”,而其他所有级别都会更改为数字。无论我是否包含 factor(speaker) 命令,都会发生这种情况:

subj | speaker | word

1        175     apple
1        86      baby
1        OTH     baby
2        86      dog
2        86      cat
2        OTH     cat

它正在将因素更改为“OTH”,但我的 ifelse 代码的 TRUE 元素似乎是问题所在。

非常感谢!

【问题讨论】:

  • 您可能希望 as.character(speaker) 作为 ifelse 的第二个参数。 R 因子实际上是整数。如果演讲者是角色,那么您在 ifelse 操作之前进行因子调用时会在脚上射击自己。之后可能会有意义。
  • 成功了!非常感谢!但我不明白为什么会发生这种情况 - 当我省略 as.factor() 命令时,R 告诉我扬声器已经是一个字符向量。
  • R 中的因子是整数 - 可以在创建因子时命名的整数。

标签: r dplyr


【解决方案1】:

由于因素,您也可以使用此解决方案。这正在生成因子级别中存在的值的索引。

new.df <- df %>%
select(subj, speaker) %>%
    mutate(speaker = ifelse(speaker %in% c("CHI", "MOT"), levels(speaker)
[speaker], "OTH")) 

因此,为了获取实际价值,我们可以使用 levels(speaker)[speaker]

【讨论】:

    【解决方案2】:

    为什么我不确定,但是如果您阅读 factor: ?factor 的帮助菜单,它会提到首先转换为 as.character。

    new.df <- data %>%
    dplyr::select(subj, speaker) %>%
        mutate(speaker = factor(speaker),
         speaker = ifelse(speaker %in% c("CHI", "MOT"), as.character(speaker), "OTH")) 
    

    【讨论】:

      【解决方案3】:

      要更改因子水平而不是字符列中的值,您需要直接使用因子的水平。您可以在基础 R 中通过使用 levels 函数或使用 RStudio 的 forcats 包中的 fct_other 函数来执行此操作。在这两种方法中,new.df 中的speaker 是具有所需级别的因素。

      这些方法如下所示:

      data <- data.frame(subj=c(1,1,1,2,2,2), speaker=c("MOT","CHI","SI1","CHI","CHI","FAT"), word=c("apply","baby","baby","dog","cat", "cat"))
      #
      # To reset selected levels in base R
      #
        new.df <- data
        new.df$speaker <- factor(new.df$speaker)
        levels(new.df$speaker)[!levels(new.df$speaker) %in% c("CHI", "MOT")] <- "OTH"
      #
      # To reset using forcats package from the RStudio suite
      #
        library(dplyr)
        library(forcats)
        new.df <- data %>% mutate(speaker = fct_other(speaker, keep=c("CHI","MOT"),
                                                      other_level = "OTH"))
        #
        # Note that speaker in new.df is a factor with the new levels
        #
         str(new.df)
      

      【讨论】:

        猜你喜欢
        • 2015-03-27
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-26
        • 2015-12-02
        • 1970-01-01
        相关资源
        最近更新 更多