R: readxl 和日期格式
R: readxl and date format
我读入了一个 excel 文件,其中 1 列包含不同格式的日期:excel 格式(例如 43596)和文本(例如“01.01.2020”)。
要转换 excel 格式,可以使用 as.Date(as.numeric(df$date), origin = "1899-12-30")
转换文本可以使用 as.Date(df$date, format = "%d.%m.%Y")
这些适用于个人价值,但当我尝试 ifelse
df$date <- ifelse(length(df$date)==5,
as.Date(as.numeric(df$date), origin = "1899-12-30"),
as.Date(df$date, format = "%d.%m.%Y"))
或for循环
for (i in length(x)) {
if(nchar(x[i])==5) {
y[i] <- as.Date(as.numeric(x[i]), origin = "1899-12-30")
} else {x[i] <- as.Date(x[i], , format = "%d.%m.%Y"))}
} print(x)
它不起作用,因为:
"character string is not in a standard unambiguous format"
也许您可以建议一个更好的解决方案来转换/替换适当的日期格式?
谢谢!
我有 2 个解决方案。
- 更改代码,我不喜欢,因为您依赖于 xlsx 日期格式:
> df <- tibble(date = c("01.01.2020","43596"))
>
> df$date <- as.Date(ifelse(nchar(df$date)==5,
+ as.Date(as.numeric(df$date), origin = "1899-12-30"),
+ as.Date(df$date, format = "%d.%m.%Y")), origin = "1970-01-01")
Warning message:
In as.Date(as.numeric(df$date), origin = "1899-12-30") :
NAs introducidos por coerción
>
> df$date
[1] "2020-01-01" "2019-05-11"
>
- 将文档保存为 CSV 文件并使用
readr
包中的 read_csv()
函数。那解决了一切!!!!
您可以使用 sapply
将 ifelse
应用于每个值:
df$date <- as.Date(sapply(df$date,function(date) ifelse(nchar(date)==5,
as.Date(as.numeric(date), origin = "1899-12-30"),
as.Date(date, format = "%d.%m.%Y"))),
origin="1970-01-01")
df
# A tibble: 6 x 2
contract date
<dbl> <date>
1 231429 2019-05-11
2 231437 2020-01-07
3 231449 2021-01-01
4 231459 2020-03-03
5 231463 2020-10-27
6 231466 2011-03-17
使用rowwise
的tidyverse
解决方案
library(dplyr)
library(lubridate)
df %>%
rowwise() %>%
mutate(date_new=as.Date(ifelse(grepl("\.",date),
as.character(dmy(date)),
as.character(as.Date(as.numeric(date), origin="1899-12-30"))))) %>%
ungroup()
# A tibble: 6 × 3
contract date date_new
<dbl> <chr> <date>
1 231429 43596 2019-05-11
2 231437 07.01.2020 2020-01-07
3 231449 01.01.2021 2021-01-01
4 231459 03.03.2020 2020-03-03
5 231463 44131 2020-10-27
6 231466 40619 2011-03-17
我读入了一个 excel 文件,其中 1 列包含不同格式的日期:excel 格式(例如 43596)和文本(例如“01.01.2020”)。
要转换 excel 格式,可以使用 as.Date(as.numeric(df$date), origin = "1899-12-30")
转换文本可以使用 as.Date(df$date, format = "%d.%m.%Y")
这些适用于个人价值,但当我尝试 ifelse
df$date <- ifelse(length(df$date)==5,
as.Date(as.numeric(df$date), origin = "1899-12-30"),
as.Date(df$date, format = "%d.%m.%Y"))
或for循环
for (i in length(x)) {
if(nchar(x[i])==5) {
y[i] <- as.Date(as.numeric(x[i]), origin = "1899-12-30")
} else {x[i] <- as.Date(x[i], , format = "%d.%m.%Y"))}
} print(x)
它不起作用,因为:
"character string is not in a standard unambiguous format"
也许您可以建议一个更好的解决方案来转换/替换适当的日期格式? 谢谢!
我有 2 个解决方案。
- 更改代码,我不喜欢,因为您依赖于 xlsx 日期格式:
> df <- tibble(date = c("01.01.2020","43596"))
>
> df$date <- as.Date(ifelse(nchar(df$date)==5,
+ as.Date(as.numeric(df$date), origin = "1899-12-30"),
+ as.Date(df$date, format = "%d.%m.%Y")), origin = "1970-01-01")
Warning message:
In as.Date(as.numeric(df$date), origin = "1899-12-30") :
NAs introducidos por coerción
>
> df$date
[1] "2020-01-01" "2019-05-11"
>
- 将文档保存为 CSV 文件并使用
readr
包中的read_csv()
函数。那解决了一切!!!!
您可以使用 sapply
将 ifelse
应用于每个值:
df$date <- as.Date(sapply(df$date,function(date) ifelse(nchar(date)==5,
as.Date(as.numeric(date), origin = "1899-12-30"),
as.Date(date, format = "%d.%m.%Y"))),
origin="1970-01-01")
df
# A tibble: 6 x 2
contract date
<dbl> <date>
1 231429 2019-05-11
2 231437 2020-01-07
3 231449 2021-01-01
4 231459 2020-03-03
5 231463 2020-10-27
6 231466 2011-03-17
使用rowwise
tidyverse
解决方案
library(dplyr)
library(lubridate)
df %>%
rowwise() %>%
mutate(date_new=as.Date(ifelse(grepl("\.",date),
as.character(dmy(date)),
as.character(as.Date(as.numeric(date), origin="1899-12-30"))))) %>%
ungroup()
# A tibble: 6 × 3
contract date date_new
<dbl> <chr> <date>
1 231429 43596 2019-05-11
2 231437 07.01.2020 2020-01-07
3 231449 01.01.2021 2021-01-01
4 231459 03.03.2020 2020-03-03
5 231463 44131 2020-10-27
6 231466 40619 2011-03-17