Tidyverse突变的困难因素

时间:2019-02-06 20:51:00

标签: r date dplyr

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

我正在尝试使用一些dydyverse函数创建第二列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"

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

2 个答案:

答案 0 :(得分:2)

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()重新设置级别,同时保留顺序。

答案 1 :(得分:1)

我认为这可以为您提供想要的东西:

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的{​​{1}}参数更改为传递的第一个参数中不存在的级别,该级别将返回factor

NA