0

我正在尝试编写一个使用 gsub 查找和替换某些字符串的函数。我有 10 多个 excel 电子表格,其中包含货币值列表,使用标准瑞典分隔符表示千位和小数,即小数用逗号而不是句点表示,千位分隔符是空格而不是逗号。英语中的 1,000.31 会变成瑞典语中的 1 000,31 吗?我正在尝试编写一个函数来消除千位分隔符所在的空格,并找到逗号并将其替换为句点。

正常的 gsub 函数工作正常:

    df$Saldo <- gsub(",", ".", df$Saldo)
    df$Saldo <- gsub(" ", "", df$Saldo)

但是,我需要在 10 多个数据帧上执行此操作,所以我认为编写一个可应用于每个数据帧的函数会更有效(下面提供了我尝试编写的函数以及可重现的示例)。这是我遇到问题的地方。我还应该提到我正在寻找一个 dplyr 解决方案。我使用该函数(如下)得到的错误是 Error: Quosures can only be unquoted in a quasiquotation context。

我承认,尽管我反复阅读了关于非标准评估和准引用的内容,但我仍然难以理解这些概念。我已阅读 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)

我想要实现的直接目标是查找逗号并将逗号替换为句点的功能。但是,我也很感激有关如何在函数中包含正则表达式以删除不需要的空格的指针。

4

1 回答 1

0

以下版本的代码可以删除逗号并用小数替换它们,还可以删除空格,但您可能希望使用 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;Number\nA;1 200,3\nB;32\nC;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;Number\nA;1200,3\nB;32\nC;2511,01"
read.csv2(text = Lines2)

给予:

  Letter  Number
1      A 1200.30
2      B   32.00
3      C 2511.01

2)转换 df或使用上面的swedish类转换:Saldodf

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))

或与 dplyr 几乎相同df %>% 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")
于 2019-06-16T12:50:14.443 回答