为什么lubridate包中的dmy()不适用于NAs?什么是好的解决方法?

为什么lubridate包中的dmy()不适用于NAs?什么是好的解决方法?,r,lubridate,R,Lubridate,我在lubridate包中偶然发现了一个特殊的行为:dmy(NA)trows一个错误,而不仅仅是返回一个NA。当我想转换一个列时,如果其中某些元素是NAs,而某些日期字符串通常转换时没有问题,这会导致问题 以下是最简单的示例: library(lubridate) df <- data.frame(ID=letters[1:5], Datum=c("01.01.1990", NA, "11.01.1990", NA, "01.02.1990")) df_copy

我在
lubridate
包中偶然发现了一个特殊的行为:
dmy(NA)
trows一个错误,而不仅仅是返回一个NA。当我想转换一个列时,如果其中某些元素是NAs,而某些日期字符串通常转换时没有问题,这会导致问题

以下是最简单的示例:

library(lubridate)
df <- data.frame(ID=letters[1:5],
              Datum=c("01.01.1990", NA, "11.01.1990", NA, "01.02.1990"))
df_copy <- df
#Question 1: Why does dmy(NA) not return NA, but throws an error?
df$Datum <- dmy(df$Datum)
Error in function (..., sep = " ", collapse = NULL)  : invalid separator
df <- df_copy
#Question 2: What's a work around?
#1. Idea: Only convert those elements that are not NAs
#RHS works, but assigning that to the LHS doesn't work (Most likely problem::
#column "Datum" is still of class factor, while the RHS is of class POSIXct)
df[!is.na(df$Datum), "Datum"] <- dmy(df[!is.na(df$Datum), "Datum"])
Using date format %d.%m.%Y.
Warning message:
In `[<-.factor`(`*tmp*`, iseq, value = c(NA_integer_, NA_integer_,  :
invalid factor level, NAs generated
df #Only NAs, apparently problem with class of column "Datum"
ID Datum
1  a  <NA>
2  b  <NA>
3  c  <NA>
4  d  <NA>
5  e  <NA>
df <- df_copy
#2. Idea: Use mapply and apply dmy only to those elements that are not NA
df[, "Datum"] <- mapply(function(x) {if (is.na(x)) {
                                 return(NA)
                               } else {
                                 return(dmy(x))
                               }}, df$Datum)
df #Meaningless numbers returned instead of date-objects
ID     Datum
1  a 631152000
2  b        NA
3  c 632016000
4  d        NA
5  e 633830400
库(lubridate)

df由于日期的格式比较简单,因此只需将
用作.Date
并指定适当的
格式
参数可能会简单得多:

df$Date <- as.Date(df$Datum, format="%d.%m.%Y")
df

  ID      Datum       Date
1  a 01.01.1990 1990-01-01
2  b       <NA>       <NA>
3  c 11.01.1990 1990-01-11
4  d       <NA>       <NA>
5  e 01.02.1990 1990-02-01

df$Date函数(…,sep=”“,collapse=NULL)中的
错误:无效分隔符
是由
lubridate:::guess_format()
函数引起的。在调用
paste()
时,
NA
将作为
sep
传递,特别是在
fmts谢谢@Andrie。我仍然对为什么
dmy
没有完成这项工作感兴趣,因为我认为这个包非常直观(否则,我总是在R;-)中处理日期,所以我没有回答它。如果没有好的解决方法或解释,我会按照你的建议,使用base
作为.Date
。因为这是一个已知的问题(),正确的步骤是下载代码,修复问题,并向软件包作者发送补丁。我的错!我仔细看了那张单子,但没发现这张。所以我会听从你的建议的!再次感谢。众所周知,
lubridate
无法正确解析
NA
值:不是解决方案,但“函数中的错误(…,sep=”“,collapse=NULL):无效分隔符”是由
lubridate:::guess_format()
函数引起的。在调用
paste()
时,
NA
作为
sep
传递,特别是在
fmts Thank@jthetzel,这澄清了问题。但是,我对
R
和开源项目的检查源代码、修复和发送补丁没有信心。希望有一天我会这样做,但在此之前,我宁愿依赖可能更稳定的base
Date
类,也不愿继续使用
lubridate
而遇到另一个问题。没问题,@Christoph_J。我对函数做了一个小补丁,修复了错误。我将向维护人员提交。同时,如果您想尝试,源代码可以在:上找到,Windows二进制代码可以在:Thank@jthetzel上找到,这非常好用。现在我在一个例子中看到了补丁是如何被提出的。
require(lubridate)
df <- data.frame(ID=letters[1:5],
    Datum=c("01.01.1990", "NA", "11.01.1990", "NA", "01.02.1990")) #NAs are quoted
df_copy <- df

df$Datum <- dmy(df$Datum)