【问题标题】:Why does dplyr's mutate() change the time format?为什么 dplyr 的 mutate() 会改变时间格式?
【发布时间】:2015-11-26 23:52:30
【问题描述】:

我使用readr 读取包含时间格式的日期列的数据。我可以使用readrcol_types 选项正确读取它。

library(dplyr)
library(readr)

sample <- "time,id
2015-03-05 02:28:11,1674
2015-03-03 13:10:59,36749
2015-03-05 07:55:48,NA
2015-03-05 06:13:19,NA
"

mydf <- read_csv(sample, col_types="Ti")
mydf
                 time    id
1 2015-03-05 02:28:11  1674
2 2015-03-03 13:10:59 36749
3 2015-03-05 07:55:48    NA
4 2015-03-05 06:13:19    NA

这很好。但是,如果我想用dplyr 操作此列,则时间列会丢失其格式。

mydf %>% mutate(time = ifelse(is.na(id), NA, time))
        time    id
1 1425522491  1674
2 1425388259 36749
3         NA    NA
4         NA    NA

为什么会这样?

我知道我可以通过之前将其转换为字符来解决此问题,但如果不来回转换会更方便。

mydf %>% mutate(time = as.character(time)) %>% 
    mutate(time = ifelse(is.na(id), NA, time))

【问题讨论】:

    标签: r dplyr readr


    【解决方案1】:

    dplyr 中有另一个版本的if_else @hadley。它正确地管理时间变量。看看this github issue

    【讨论】:

      【解决方案2】:

      实际上是ifelse() 导致了这个问题,而不是dplyr::mutate()。属性剥离问题的例子见help(ifelse) -

      ## ifelse() strips attributes
      ## This is important when working with Dates and factors
      x <- seq(as.Date("2000-02-29"), as.Date("2004-10-04"), by = "1 month")
      ## has many "yyyy-mm-29", but a few "yyyy-03-01" in the non-leap years
      y <- ifelse(as.POSIXlt(x)$mday == 29, x, NA)
      head(y) # not what you expected ... ==> need restore the class attribute:
      class(y) <- class(x)
      

      所以你有它。如果您想使用ifelse(),这需要做一些额外的工作。这里有两种可能的方法可以让您在没有ifelse() 的情况下获得您想要的结果。第一个非常简单,使用is.na&lt;-

      ## mark 'time' as NA if 'id' is NA
      is.na(mydf$time) <- is.na(mydf$id)
      
      ## resulting in
      mydf
      #                  time    id
      # 1 2015-03-05 02:28:11  1674
      # 2 2015-03-03 13:10:59 36749
      # 3                <NA>    NA
      # 4                <NA>    NA
      

      如果您不想选择该路线,并希望继续使用dplyr 方法,您可以使用replace() 而不是ifelse()

      mydf %>% mutate(time = replace(time, is.na(id), NA))
      #                  time    id
      # 1 2015-03-05 02:28:11  1674
      # 2 2015-03-03 13:10:59 36749
      # 3                <NA>    NA
      # 4                <NA>    NA
      

      数据:

      mydf <- structure(list(time = structure(c(1425551291, 1425417059, 1425570948, 
      1425564799), class = c("POSIXct", "POSIXt"), tzone = ""), id = c(1674L, 
      36749L, NA, NA)), .Names = c("time", "id"), class = "data.frame", row.names = c(NA, 
      -4L))
      

      【讨论】:

        猜你喜欢
        • 2021-10-15
        • 2016-06-24
        • 1970-01-01
        • 2021-04-28
        • 2013-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多