如何在同一列中导入混合日期类型的 xlsx?
How to import xlsx with mixed date types in same column?
我正在尝试将 Excel 电子表格导入 R(通过 read.xlsx2()
)。 Excel 数据有一个日期列。该日期列包含混合类型的日期格式,例如有些行是 42669
,有些是日期格式,例如26/10/2016
.
read.xlsx2()
将其作为一个因素读入,因此我使用下面的代码将其转换为 as.Date。这适用于所有数字形式的日期(例如 42669
),但 R 警告我它添加了一些 NA
s(对于 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
如果有必要,我们可以应用一个函数来清理日期,基本上是这样的:
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
这是一种方法,
读入数据后,我们将日期列 (df$recd_date) 转换为 class 字符,然后创建两个列表,一个包含 dd/mm/YYYY 日期,另一个包含其他带有数字日期。完成后,我们独立转换为日期 class,然后将两者合并以获得最终产品。
#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
尝试使用 janitor 包中的 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 日期数字和格式化日期的确切问题。
我正在尝试将 Excel 电子表格导入 R(通过 read.xlsx2()
)。 Excel 数据有一个日期列。该日期列包含混合类型的日期格式,例如有些行是 42669
,有些是日期格式,例如26/10/2016
.
read.xlsx2()
将其作为一个因素读入,因此我使用下面的代码将其转换为 as.Date。这适用于所有数字形式的日期(例如 42669
),但 R 警告我它添加了一些 NA
s(对于 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
如果有必要,我们可以应用一个函数来清理日期,基本上是这样的:
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
这是一种方法,
读入数据后,我们将日期列 (df$recd_date) 转换为 class 字符,然后创建两个列表,一个包含 dd/mm/YYYY 日期,另一个包含其他带有数字日期。完成后,我们独立转换为日期 class,然后将两者合并以获得最终产品。
#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
尝试使用 janitor 包中的 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 日期数字和格式化日期的确切问题。