ifelse和POSIXct:NA的强制和默认类

时间:2018-03-06 16:36:25

标签: r date types posix na

以下是我的例子:

library(dplyr)
my_df <- data.frame(col_1 = c(1,2,4), col_2 = c('2017-12-1', '2015-11-2', '2011-2-5'))
my_df$col_2 <- as.POSIXct(my_df$col_2)
out <- ifelse(my_df$col_1 ==2, my_df$col_2+ as.difftime(3, units = 'days'), NA)
print(out)

它产生:

NA 1446703200         NA

因此,由于数据类型不同而发生强制。我应该使用哪种NA数据类型来阻止它:NA_date_NA_POSIX_或......?

3 个答案:

答案 0 :(得分:1)

最好使用分配而不是ifelse逐步执行此操作。

1)创建索引

i1 <- my_df$col_1 == 2

2)根据指数分配值

my_df$col_2[i1] <- my_df$col_2[i1] + as.difftime(3, units = 'days')

3)将其他元素更改为NA

my_df$col_2[!i1] <- NA
my_df
#  col_1      col_2
#1     1       <NA>
#2     2 2015-11-05
#3     4       <NA>

原因是POSIXct存储模式为numeric,在ifelse内被强制转换为numeric格式

如果我们使用tidyverse,那么

library(tidyverse)
my_df %>%
    mutate(col_2 =  col_2 + days(3), 
           col_2 = replace(col_2, col_1 != 2, NA))

答案 1 :(得分:1)

data.table可以轻松修改特定行

require(data.table)
my_df <- data.frame(col_1 = c(1,2,4), col_2 = c('2017-12-1', '2015-11-2', '2011-2-5'))
setDT(my_df)
my_df[, col_2 := as.POSIXct(col_2)
      ][col_1 == 2, col_2 := col_2 + as.difftime(3, units = 'days')
      ][col_1 != 2, col_2 := NA]

答案 2 :(得分:1)

因为您(由于某种原因;))已加载dplyr,您可以使用if_else并将false NA打包在as.POSIXct *:< / p>

if_else(my_df$col_1 == 2, my_df$col_2 + as.difftime(3, units = 'days'), as.POSIXct(NA))
# [1] NA               "2015-11-05 CET" NA 

*请参阅?as.POSIXct

  

逻辑NA可以转换为[POSIXltPOSIXct]

类中的任何一个

相关问题:

How to prevent ifelse() from turning Date objects into numeric objects。另请参阅the comment by @roarkz和我的回答。