如何在同一列中导入具有混合日期类型的xlsx?

时间:2019-01-31 14:26:16

标签: r date xlsx

我正在尝试将Excel电子表格导入到R中(通过read.xlsx2())。 Excel数据具有日期列。该日期列包含多种类型的日期格式,例如有些行是42669,有些则是日期格式,例如26/10/2016

read.xlsx2()会将其读取为一个因素,因此我使用以下代码将其转换为as.Date。这适用于所有数字形式的日期(例如42669),但R警告我它添加了一些NA(对于格式为26/10/2016的日期)。我的问题是如何导入具有所有变量正确日期的excel数据,即告诉R有混合数据?

library(xlsx)
#Import excel file
df <- read.xlsx2(mydata, 1, header=true)

#Output = recd_date : Factor w/ 590 levels "", "26/10/2016", "42669" ...
levels(df$recd_date)

#Output = [1] "" "26/10/2016" "42669" ...

#This works for numeric dates: 

df$recd_date <- as.Date( as.numeric (as.character(df$recd_date) ),origin="1899-12-30")

#Output = recd_date : Date, format "2016-10-26" ...

#but it doesn't work for dd/mm/yyyy dates, R just replaces these with NA

3 个答案:

答案 0 :(得分:1)

如果需要,我们可以应用一个函数来清除日期,基本上是这样的:

cleanDate <- function(x) {
  if (all(nchar(df2$date.mix) < 10)) {
    cd <- as.Date(x)
  } else {
    cd <- do.call(c, 
                  lapply(x, function(i)
                    if (nchar(i) < 10)  
                      as.Date(as.numeric(i), origin="1970-01-01")
                    else as.Date(i)))
  }
  return(cd)
}

示例

# generate test df
df1 <- data.frame(date.chr=as.character(as.Date(1:3, origin=Sys.Date())), 
                  date.num=as.numeric(as.Date(1:3, origin=Sys.Date())),
                  date.mix=as.character(as.Date(1:3, origin=Sys.Date())),
                  stringsAsFactors=FALSE)

df1[2, 3] <- as.character(as.numeric(as.Date(df1[2, 1])))
> df1
    date.chr date.num   date.mix
1 2019-02-01    17928 2019-02-01
2 2019-02-02    17929      17929
3 2019-02-03    17930 2019-02-03

# write it to working directory
library(xlsx)
write.xlsx2(df1, "df1.xlsx")

# read it
# we use opt. `stringsAsFactors=FALSE` to prevent generation of factors
df2 <- read.xlsx2("df1.xlsx", 1, stringsAsFactors=FALSE)
> df2
  X.   date.chr date.num   date.mix
1  1 2019-02-01    17928 2019-02-01
2  2 2019-02-02    17929      17929
3  3 2019-02-03    17930 2019-02-03

现在,我们使用lapply()应用该功能。

date.cols <- c("date.chr", "date.num", "date.mix")  # select date columns
df2[date.cols] <- lapply(df2[date.cols], cleanDate)

结果

> df2
  X.   date.chr   date.num   date.mix
1  1 2019-02-01 2019-02-01 2019-02-01
2  2 2019-02-02 2019-02-02 2019-02-02
3  3 2019-02-03 2019-02-03 2019-02-03

答案 1 :(得分:0)

这是一种实现方法,

一旦我们读入数据,就将日期列(df $ recd_date)转换为类字符,然后创建两个列表,一个带有dd / mm / YYYY日期,另一个带有数字日期。完成此操作后,我们将独立转换为日期类,然后将两者合并以得到最终产品。

#Test Data, read in anyway you want
data<-c("26/10/2016","27/10/2016","42669","52673","28/10/2016")
Index<-c(1:5)
df<-data.frame(Index, date=data)

#Put entire date column into character format
df$date<-as.character(df$date)

#Create Date from Numeric Date, Create Date from Character Date
Date_N<-as.Date(as.numeric(df$date),origin="1899-12-30")
Date_C<-as.Date(as.character(df$date),format="%d/%m/%Y")

#Create DF from list
Date_N_df<-as.data.frame(Date_N)
Date_C_df<-as.data.frame(Date_C)

#Replace NA from Date_C_df with index from Date_N_df
Date_C_df[is.na(Date_C_df)] <- Date_N_df[is.na(Date_C_df)]
Final<-Date_C_df 
names(Final)<-"Date"

> Final
        Date
1 2016-10-26
2 2016-10-27
3 2016-10-26
4 2044-03-17
5 2016-10-28

答案 2 :(得分:0)

尝试使用看门人软件包中的convert_to_date,并从lubridate软件包中指定与您的日期格式匹配的字符至日期函数:

library(janitor)
x <- c("26/10/2016", "42669")
convert_to_date(x, character_fun = lubridate::dmy)
#> [1] "2016-10-26" "2016-10-26"

自我促销免责声明:我维护此程序包。我要添加此答案,因为创建此函数是为了解决将Excel日期数字和带格式的日期混合在同一变量中的确切问题。