我正在尝试编写一个使用 gsub 查找和替换某些字符串的函数。我有 10+ 个 excel 电子表格,其中包含使用标准瑞典语分隔符的货币值列表,用于千和小数,即小数点由逗号而不是句点表示,千位分隔符是空格而不是逗号。英语中的 1,000.31 在瑞典语中会变成 1 000,31?我正在尝试编写一个函数,该函数将消除千位分隔符所在的空格,并找到逗号并将其替换为句点。
正常的 gsub 函数工作正常:
df$Saldo <- gsub(",", ".", df$Saldo)
df$Saldo <- gsub(" ", "", df$Saldo)
但是,我需要在 10+ 个数据帧上执行此操作,因此我认为编写一个可以应用于每个数据帧的函数会更有效(下面提供了我尝试编写的函数以及可重现的示例)。这就是我遇到问题的地方。我还应该提到我正在寻找 dplyr 解决方案。我在函数(下面)中得到的错误是错误:商数只能在准报价上下文中取消引用。
我承认,尽管已经阅读并重读了非标准评估和准引用,但我仍然难以理解这些概念。我读过使用 dplyr 编程
https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html。
我还读过:
https://rlang.r-lib.org/reference/quasiquotation.html。
最后,我研究了几个关于堆栈溢出的模糊相似的问题/解决方案,但那里的解决方案似乎对我不起作用。大多数问题都涉及让正则表达式工作,而不是让正则表达式在函数中工作。
这是函数,例如:
library(dplyr)
replace_commas <- function(df1, c_name) {
c_name <- enquo(c_name)
df1 <- df1 %>% gsub(",", ".",!! c_name)
return(df1)
}
这是一个可重现的示例:
df <- data.frame(Date = c("2018-12-15", "2018-11-04", "2018-10-26"), Saldo = c("123 432,45", "87 546,23", "9 564,82"))
df_new <- replace_commas(df, Saldo)
我想要实现的直接事情是一个查找逗号并将其替换为句点的函数。但是,我也希望获得有关如何在函数中包含正则表达式以删除不需要的空格的指针。
以下版本的代码用于删除逗号并将其替换为小数,还可以删除空格,但您可能希望使用 R 的内置工具,如下所示。
library(dplyr)
as.swedish <- function(from) as.numeric(gsub(" ", "", sub(",", ".", from)))
replace_commas <- function(df1, c_name) {
c_name <- enquo(c_name)
df1 %>% mutate_at(vars(!!c_name), as.swedish)
}
df %>% replace_commas(Saldo)
下面假设有空格作为千位分隔符,逗号作为小数,但 1a 除外,它只假设逗号作为小数。
1) read.csv2我们可以定义一个swedish
类,然后在read.csv2
中使用它。 这使用上面定义的单行函数as.swedish
。
# test data
Lines <- "Letter;NumbernA;1 200,3nB;32nC;2511,01"
# define swedish class
setClass("swedish")
setAs("character", "swedish", as.swedish)
setAs("factor", "swedish", as.swedish)
read.csv2(text = Lines, colClasses = list(Number = "swedish"))
给:
Letter Number
1 A 1200.30
2 B 32.00
3 C 2511.01
1a)如果我们没有空格作为千位分隔符,只有逗号作为小数,那么我们可以使用 read.csv2:
Lines2 <- "Letter;NumbernA;1200,3nB;32nC;2511,01"
read.csv2(text = Lines2)
给:
Letter Number
1 A 1200.30
2 B 32.00
3 C 2511.01
2)转换DF或使用上面的swedish
类在df
中转换Saldo
:
transform(df, Saldo = as(Saldo, "swedish"))
给:
Date Saldo
1 2018-12-15 123432.45
2 2018-11-04 87546.23
3 2018-10-26 9564.82
2a)这也有效,并且仅使用上面的as.swedish
函数,而不使用swedish
类。
transform(df, Saldo = as.swedish(Saldo))
或与 DPLYRdf %>% mutate(Saldo = as.swedish(Saldo))
几乎相同
3) 转换 df或定义此函数的函数,其中names
是要从瑞典语转换的列名的字符向量。 如果我们将名称作为字符串传递,则不需要准引号或相应的内置 R 工具,这似乎是一个更好的设计。 这使用上面的as.swedish
函数,但不使用swedish
类。
swedish <- function(data, names) replace(data, names, lapply(data[names], as.swedish))
swedish(df, "Saldo")
或
library(dplyr)
df %>% swedish("Saldo")