自定义函数来处理 excel 尝试使用卷曲卷曲的不同日期格式
custom function to handle different date formats from excel trying to use curly curly
我有一个从 excel 导入的数据框,read_excel
看起来像这样:
主要任务是处理不同格式的日期:
我想把它实现成一个自定义函数(而且我不擅长创建函数):
df <- structure(list(date = c("40574", "40861", "40870", "40990", "07.03.2022",
"14.03.2022", "16.03.2022", "27.03.2022", "24.03.2022", "24.03.2022"
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))
# A tibble: 10 x 1
date
<chr>
1 40574
2 40861
3 40870
4 40990
5 07.03.2022
6 14.03.2022
7 16.03.2022
8 27.03.2022
9 24.03.2022
10 24.03.2022
我用这段代码解决了这个任务:
library(tidyverse)
library(janitor)
library(lubridate)
df %>%
mutate(new_col = excel_numeric_to_date(as.numeric(as.character(date)), date_system = "modern"), .before=1) %>%
mutate(date = ifelse(!str_detect(date, '\.'), NA_character_, date)) %>%
mutate(date = dmy(date)) %>%
mutate(date = coalesce(date, new_col), .keep="unused")
从这段代码我想用这段代码制作一个自定义函数:
mixed_dateColumn_excel <- function(df, x) {
x <- {{x}}
df %>%
mutate(new_col = excel_numeric_to_date(as.numeric(as.character(x)), date_system = "modern"), .before=1) %>%
mutate(x = ifelse(!str_detect(x, '\.'), NA_character_, x)) %>%
mutate(x = dmy(x)) %>%
mutate(x = coalesce(x, new_col), .keep="unused")
}
我想知道为什么:
这不行:
mixed_dateColumn_excel(df, "date")
这也行不通:
mixed_dateColumn_excel(df, date)
这有效:
mixed_dateColumn_excel(df, df$date)
您不能使用 curly-curly 运算符 TarJae 以这种方式取消引用。它必须直接在 tidyverse 函数中完成。
在您的版本中,行:
x <- {{x}}
实际上没有做任何事情 - 如果您完全删除此行,您将得到相同的结果。你使用 df$date
的第三个版本 真的 不起作用,因为它创建了一个名为 x
的列,并在 mutate
函数中进行了计算简单地处理传递的向量 df$date
。带有 "date"
的版本不起作用,因为您要为计算传递一个文字字符串,并且 date
不起作用,因为如果不正确使用数据屏蔽,R 无法找到该变量。
也许最简单的方法是使用 rlang::ensym
,因为您还想对 mutate
中的列名称使用不带引号的 x
,但您仍然需要使用 bang-bang 运算符取消引用,并且在分配列时需要赋值运算符 :=
mixed_dateColumn_excel <- function(df, x) {
x <- rlang::ensym(x)
df %>%
mutate(new_col = suppressWarnings(janitor::excel_numeric_to_date(
as.numeric(as.character(!!x)),
date_system = "modern")), .before = 1) %>%
mutate(!!x := ifelse(!str_detect(!!x, '\.'), NA_character_, !!x)) %>%
mutate(!!x := lubridate::dmy(!!x)) %>%
mutate(!!x := coalesce(!!x, new_col), .keep="unused")
}
mixed_dateColumn_excel(df, date)
#> # A tibble: 10 x 1
#> date
#> <date>
#> 1 2011-01-31
#> 2 2011-11-14
#> 3 2011-11-23
#> 4 2012-03-22
#> 5 2022-03-07
#> 6 2022-03-14
#> 7 2022-03-16
#> 8 2022-03-27
#> 9 2022-03-24
#> 10 2022-03-24
由 reprex package (v2.0.1)
于 2022-04-12 创建
{{
不是真正的运算符,tidyverse 函数旨在在参数中识别它并发挥一些魔力。
{{
也可以用在名称中,所以这里不需要 ensym()
,你可以这样做:
mixed_dateColumn_excel <- function(df, x) {
df %>%
mutate(
new_col = excel_numeric_to_date(
as.numeric(as.character({{ x }})),
date_system = "modern"
),
.before = 1
) %>%
mutate("{{ x }}" := ifelse(!str_detect({{ x }}, '\.'), NA_character_, {{ x }})) %>%
mutate("{{ x }}" := lubridate::dmy({{ x }})) %>%
mutate("{{ x }}" := coalesce({{ x }}, new_col), .keep="unused")
}
与你关于函数编程的问题分开,但万一有人来这里寻找解决原始问题的方法:你可以用一个看门函数来解决这个问题,更强大的 convert_to_date()
在 excel_numeric_to_date()
.
library(tidyverse)
library(janitor)
df %>%
mutate(new_col = convert_to_date(date, character_fun = lubridate::dmy))
# A tibble: 10 x 2
date new_col
<chr> <date>
1 40574 2011-01-31
2 40861 2011-11-14
3 40870 2011-11-23
4 40990 2012-03-22
5 07.03.2022 2022-03-07
6 14.03.2022 2022-03-14
7 16.03.2022 2022-03-16
8 27.03.2022 2022-03-27
9 24.03.2022 2022-03-24
10 24.03.2022 2022-03-24
它首先转换 Excel 个数字,然后对剩余值应用日期转换函数。
我有一个从 excel 导入的数据框,read_excel
看起来像这样:
主要任务是处理不同格式的日期:
我想把它实现成一个自定义函数(而且我不擅长创建函数):
df <- structure(list(date = c("40574", "40861", "40870", "40990", "07.03.2022",
"14.03.2022", "16.03.2022", "27.03.2022", "24.03.2022", "24.03.2022"
)), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))
# A tibble: 10 x 1
date
<chr>
1 40574
2 40861
3 40870
4 40990
5 07.03.2022
6 14.03.2022
7 16.03.2022
8 27.03.2022
9 24.03.2022
10 24.03.2022
我用这段代码解决了这个任务:
library(tidyverse)
library(janitor)
library(lubridate)
df %>%
mutate(new_col = excel_numeric_to_date(as.numeric(as.character(date)), date_system = "modern"), .before=1) %>%
mutate(date = ifelse(!str_detect(date, '\.'), NA_character_, date)) %>%
mutate(date = dmy(date)) %>%
mutate(date = coalesce(date, new_col), .keep="unused")
从这段代码我想用这段代码制作一个自定义函数:
mixed_dateColumn_excel <- function(df, x) {
x <- {{x}}
df %>%
mutate(new_col = excel_numeric_to_date(as.numeric(as.character(x)), date_system = "modern"), .before=1) %>%
mutate(x = ifelse(!str_detect(x, '\.'), NA_character_, x)) %>%
mutate(x = dmy(x)) %>%
mutate(x = coalesce(x, new_col), .keep="unused")
}
我想知道为什么:
这不行:
mixed_dateColumn_excel(df, "date")
这也行不通:
mixed_dateColumn_excel(df, date)
这有效:
mixed_dateColumn_excel(df, df$date)
您不能使用 curly-curly 运算符 TarJae 以这种方式取消引用。它必须直接在 tidyverse 函数中完成。
在您的版本中,行:
x <- {{x}}
实际上没有做任何事情 - 如果您完全删除此行,您将得到相同的结果。你使用 df$date
的第三个版本 真的 不起作用,因为它创建了一个名为 x
的列,并在 mutate
函数中进行了计算简单地处理传递的向量 df$date
。带有 "date"
的版本不起作用,因为您要为计算传递一个文字字符串,并且 date
不起作用,因为如果不正确使用数据屏蔽,R 无法找到该变量。
也许最简单的方法是使用 rlang::ensym
,因为您还想对 mutate
中的列名称使用不带引号的 x
,但您仍然需要使用 bang-bang 运算符取消引用,并且在分配列时需要赋值运算符 :=
mixed_dateColumn_excel <- function(df, x) {
x <- rlang::ensym(x)
df %>%
mutate(new_col = suppressWarnings(janitor::excel_numeric_to_date(
as.numeric(as.character(!!x)),
date_system = "modern")), .before = 1) %>%
mutate(!!x := ifelse(!str_detect(!!x, '\.'), NA_character_, !!x)) %>%
mutate(!!x := lubridate::dmy(!!x)) %>%
mutate(!!x := coalesce(!!x, new_col), .keep="unused")
}
mixed_dateColumn_excel(df, date)
#> # A tibble: 10 x 1
#> date
#> <date>
#> 1 2011-01-31
#> 2 2011-11-14
#> 3 2011-11-23
#> 4 2012-03-22
#> 5 2022-03-07
#> 6 2022-03-14
#> 7 2022-03-16
#> 8 2022-03-27
#> 9 2022-03-24
#> 10 2022-03-24
由 reprex package (v2.0.1)
于 2022-04-12 创建{{
不是真正的运算符,tidyverse 函数旨在在参数中识别它并发挥一些魔力。
{{
也可以用在名称中,所以这里不需要 ensym()
,你可以这样做:
mixed_dateColumn_excel <- function(df, x) {
df %>%
mutate(
new_col = excel_numeric_to_date(
as.numeric(as.character({{ x }})),
date_system = "modern"
),
.before = 1
) %>%
mutate("{{ x }}" := ifelse(!str_detect({{ x }}, '\.'), NA_character_, {{ x }})) %>%
mutate("{{ x }}" := lubridate::dmy({{ x }})) %>%
mutate("{{ x }}" := coalesce({{ x }}, new_col), .keep="unused")
}
与你关于函数编程的问题分开,但万一有人来这里寻找解决原始问题的方法:你可以用一个看门函数来解决这个问题,更强大的 convert_to_date()
在 excel_numeric_to_date()
.
library(tidyverse)
library(janitor)
df %>%
mutate(new_col = convert_to_date(date, character_fun = lubridate::dmy))
# A tibble: 10 x 2
date new_col
<chr> <date>
1 40574 2011-01-31
2 40861 2011-11-14
3 40870 2011-11-23
4 40990 2012-03-22
5 07.03.2022 2022-03-07
6 14.03.2022 2022-03-14
7 16.03.2022 2022-03-16
8 27.03.2022 2022-03-27
9 24.03.2022 2022-03-24
10 24.03.2022 2022-03-24
它首先转换 Excel 个数字,然后对剩余值应用日期转换函数。