【问题标题】:Tidyverse mutation difficulties with factorsTidyverse 突变困难与因素
【发布时间】:2019-02-06 20:50:59
【问题描述】:
library(tidyverse)
library(lubridate)
library(stringr)
df <- tibble(YrMo = as.factor(str_sub(ymd(c("2014-01-19", "2014-02-14")),1,7)))
df
#>  YrMo   
#>  <fct>  
#>  1 2014-01
#>  2 2014-02

我正在尝试使用一些 tidyverse 函数创建第二列 YrMo2。两个预期输出是2014-Jan2014-Feb,但我得到的是NA

df %>% 
  mutate(
    YrMo2 = 
      factor(YrMo, 
             levels = format(as.Date(paste0(levels(YrMo), "-01")), "%Y-%b")
             )
    )

#> # A tibble: 2 x 2
#>   YrMo      YrMo2
#>   <fct>     <fct>
#>   1 2014-01 NA   
#>   2 2014-02 NA 

我“知道”这应该有效,因为 base-R 函数有效:

format(as.Date(paste0(levels(df$YrMo), "-01")), "%Y-%b")
#> [1] "2014-Jan" "2014-Feb"

看来我的语法是关闭的。但是哪里?或许这是我的逻辑。

【问题讨论】:

  • 使用factor()创建新因子时,levels=需要实际匹配向量中的值。如果它们不匹配,则将它们编码为 NA。如果您想要不同的名称,请按照与对应的levels= 匹配的顺序使用labels=
  • 我建议不要过度广泛地使用library(tidyverse)。它是一个方便的元包,可用于确保安装其所有依赖包,但是当您只需要(在此示例中)三个包时加载所有内容有点笨拙。在这种情况下,我会将其减少到 dplyr 代替 tidyverse

标签: r date dplyr


【解决方案1】:

forcats 包具有辅助函数,可以更轻松地处理关卡 如果你从一个字符串开始,那么你可以这样做

library(forcats)
df <- tibble(YrMo = str_sub(ymd(c("2014-01-19", "2014-02-14")),1,7))
df %>% mutate(
  YrMo2 = fct_relabel(factor(YrMo, levels=sort(YrMo)), ~format(as.Date(paste0(.x, "-01")), "%Y-%b"))
)

我们使用factor(YrMo, levels=sort(YrMo)) 确保对值进行正确排序,然后使用fct_relabel() 重新格式化级别,同时保留顺序。

【讨论】:

    【解决方案2】:

    我认为这会给你你想要的:

    df %>% 
      mutate(
        YrMo2 = factor(
          format(as.Date(paste0(YrMo, "-01")), "%Y-%b"), 
          levels = format(as.Date(paste0(levels(YrMo), "-01")), "%Y-%b")
        )
      )
    # A tibble: 2 x 2
    #  YrMo    YrMo2   
    #  <fct>   <fct>   
    #1 2014-01 2014-Jan
    #2 2014-02 2014-Feb
    

    您的问题是您将 levels 参数更改为 factor 到传递的第一个参数中不存在的级别,这将返回 NA

    factor("X", levels = "x")
    #[1] <NA>
    #Levels: x
    

    【讨论】:

    • 我将如何指定按时间顺序排列的级别?在 base-R 中,它的含义如下:x &lt;- as.factor(c("2019-01", "2019-02", "2019-03")); levels(x) &lt;- format(as.Date(paste0(levels(x), "-01")), "%Y-%b"); levels(x)您介意在答案中包含它吗?
    • 查看我的编辑,这应该保留YrMo2 中的级别顺序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多