代码之家  ›  专栏  ›  技术社区  ›  Darren Tsai

drop_na()无法在POSIX lt对象上工作

  •  2
  • Darren Tsai  · 技术社区  · 7 年前

    根据标题,我做了一个简单的例子来测试 drop_na {tidyr} :

    library(tidyr)
    library(dplyr)
    
    # (1.) produce a dataset with two POSIX type "ct" and "lt"
    
    data <- data.frame(n = 1:5)
    data$ct <- as.POSIXct(Sys.time() + rnorm(5) * 1000)
    data$lt <- as.POSIXlt(Sys.time() + rnorm(5) * 1000)
    str(data)
    
    # $ n : int  1 2 3 4 5
    # $ ct: POSIXct, format: "2018-10-07 03:02:28" ...
    # $ lt: POSIXlt, format: "2018-10-07 02:37:26" ...
    
    
    # (2.) assign the third values of "ct" and "lt" to NA
    
    data[3, c("ct", "lt")] <- NA
    
    
    # (3.) use different function to remove rows with NA
    
    data %>% is.na()               # identify NAs in both "ct" and "lt"
    data %>% drop_na('ct')         # drop NA from "ct"
    data %>% drop_na('lt')         # NOT drop NA from "lt"
    data[c(1, 2)] %>% na.omit()    # drop NA from "ct"
    data[c(1, 3)] %>% na.omit()    # NOT drop NA from "lt"
    

    从上面的结论来看,如果POSIX lt变量中有NAs,那么 is.na() 可以使用NAs删除行。

    • POSIXct 以数字向量表示自1970年初以来的秒数。
    • POSIXlt 表示的向量的命名列表。

    波西克尔特 的缺失值无法通过 drop_na() na.omit() ?

    1 回复  |  直到 7 年前
        1
  •  5
  •   lebatsnok    7 年前

    简而言之:除非你真的需要POSIXlt,否则就使用POSIXct

    长答案:

    POSIXlt是一种复杂多变的数据结构。请参见:

    > str(c(as.POSIXlt(Sys.time()), NA))
     POSIXlt[1:2], format: "2018-10-07 00:43:06" NA
    > unclass(c(as.POSIXlt(Sys.time()), NA))
    $sec
    [1] 15.78872       NA
    
    $min
    [1] 43 NA
    
    $hour
    [1]  0 NA
    # skipped a few rows
    
    $isdst
    [1]  1 -1
    
    $zone
    [1] "EEST" ""   
    # skipped a few rows 
    

    简而言之,POSIXlt是一个向量列表,每个向量表示一个日期/时间单位:秒、分钟、小时、天等,但也表示时区等。没有方法来 na.omit na.omit.default POSIXlt

    > na.omit(list(NA,NA,NA))
    [[1]]
    [1] NA
    
    [[2]]
    [1] NA
    
    [[3]]
    [1] NA
    

    如果你需要 不,省略 方法 ,你可以写一个。但如果不是真的,它更容易使用 POSIXct

    推论: 不,省略 也不能真正用于列表(即,它可以使用,但不起任何作用)。你可以 sapply lapply 省略列表,但这也会产生奇怪的结果( NA 部件将替换为 logical(0) ). 看起来像 不,省略 不适用于列表,包括 波西克尔特 .

    > foo <- as.POSIXlt(Sys.time())
    > foo
    [1] "2018-10-07 01:06:22 EEST"
    > foo$year
    [1] 118
    > foo$mon
    [1] 9
    > foo$mon <- 10
    > foo
    [1] "2018-11-07 01:06:22 EEST"
    > foo$year <- 2018
    > foo
    [1] "3918-11-07 01:06:22 EEST"
    

    > library(lubridate)
    > year(foo)
    [1] 3918
    > year(foo) <- 2018
    > foo
    [1] "2018-11-07 01:06:22 EET"
    > month(foo)
    [1] 11
    > month(foo)<-10
    > foo
    [1] "2018-10-07 01:06:22 EEST"