【问题标题】:Lubridate periods get messed up after using dplyr spread使用 dplyr spread 后润滑期变得混乱
【发布时间】:2024-11-20 21:35:01
【问题描述】:

我正在使用 R-3.6.3、lubridate_1.7.4、dbplyr_1.4.2。

代表:

df_0 <- tibble(period_type  = c("a", "b", "c"), 
               period_value = c("1:1:1", "2:2:2", "4:4:4")) %>% 
        mutate(period_value = hms(period_value))

df_0
## A tibble: 3 x 2
#  period_type period_value
#  <chr>       <Period>
#1 a           1H 1M 1S
#2 b           2H 2M 2S
#3 c           4H 4M 4S

到目前为止一切顺利。 现在使用 dplyr 传播:

df_0 %>% spread(period_type, period_value)
## A tibble: 1 x 3
#  a        b        c
#  <Period> <Period> <Period>
#1 1H 1M 1S 1H 1M 2S 1H 1M 4S

但结果应该是

## A tibble: 1 x 3
#  a        b        c
#  <Period> <Period> <Period>
#1 1H 1M 1S 2H 2M 2S 4H 4M 4S

小时和分钟搞砸了,但奇怪的是没有秒。 这是一个错误还是我做错了什么?

【问题讨论】:

  • spread 已停用,因此报告奇怪的结果不会引起太多关注。试试pivot_wider
  • 感谢您指出pivot_wider。更多信息在pivot vignette

标签: r dplyr lubridate period spread


【解决方案1】:

正如 Edward 评论的那样,pivot_wider() 已取代 spread()。但是,它似乎没有处理 period 类的变量。所以你需要转换周期值,旋转,然后再转换回来。

library(dplyr)
library(lubridate)

df_0 %>%
  mutate(period_value = period_to_seconds(period_value)) %>%
  pivot_wider(names_from = period_type, values_from = period_value) %>%
  mutate_all(seconds_to_period)

# A tibble: 1 x 3
  a        b        c       
  <Period> <Period> <Period>
1 1H 1M 1S 2H 2M 2S 4H 4M 4S

【讨论】:

  • 确实,单独pivot-wider 并不能解决问题。至少它会抛出一个错误:df_0 %&gt;% pivot_wider(names_from = period_type, values_from = period_value)Error: No common type for `value` &lt;Period&gt; and `x` &lt;Period&gt;.。感谢您的解决方法。
  • 这是一个奇怪的错误,所以我仍然在github上提出了一个问题。
【解决方案2】:

问题不在于 tidyr 动词,如 spread() isn't going away but is no longer under active development

尝试使用 hms 包的函数 parse_hms() 代替 lubridate:

df_0 <- tibble(period_type  = c("a", "b", "c"), 
           period_value = c("1:1:1", "2:2:2", "4:4:4")) %>% 
  mutate(period_value = hms::parse_hms(period_value))

df_0 %>% spread(period_type, period_value)
# or
df_0 %>% pivot_wider(names_from=period_type, values_from=period_value)

# A tibble: 1 x 3
  a        b        c       
  <time>   <time>   <time>  
1 01:01:01 02:02:02 04:04:04

【讨论】: