Проблема с кавычками и квази-цитатой и регулярными выражениями внутри функции в R - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь написать функцию, которая использует gsub для поиска и замены определенных строк. У меня есть 10+ таблиц Excel со списком денежных значений, в которых используются стандартные шведские разделители для тысяч и десятичных разрядов, то есть десятичная запятая отмечается запятой, а не точкой, а разделитель тысяч - это пробел, а не запятая. Что на английском будет 1000,31, станет 1 000,31 на шведском? Я пытаюсь написать функцию, которая устранит пространство, в котором находится разделитель тысяч, и найдет запятую и заменит ее точкой.

Нормальные функции gsub работают нормально:

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

Однако мне нужно будет сделать это на 10+ фреймах данных, поэтому я подумал, что было бы эффективнее написать функцию, которую можно было бы применить к каждому фрейму данных (функция, которую я пытался написать плюс воспроизводимый пример, представлена ​​ниже ). Здесь я сталкиваюсь с проблемами. Я должен также упомянуть, что я ищу решение dplyr. Ошибка, которую я получаю с помощью функции (см. Ниже): Ошибка: кавычки можно заключать в кавычки только в контексте квази-цитаты.

Я признаю, что, несмотря на то, что я прочитал и перечитал о нестандартной оценке и квази-цитате, мне все еще трудно понять эти концепции. Я прочитал Программирование с dplyr

https://cran.r -project.org / веб / пакеты / dplyr / виньетки / programming.html .

Я также прочитал:

https://rlang.r -lib.org / ссылка / 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)

Непосредственная вещь, которую я хочу достичь, - это функция, которая находит и заменяет запятые точками. Однако я также был бы признателен за указание на то, как включить в функцию регулярное выражение для удаления ненужных пробелов.

1 Ответ

0 голосов
/ 16 июня 2019

Следующая версия вашего кода работает для удаления запятых и замены их десятичными дробями, а также для удаления пробелов, но вы можете использовать встроенные средства 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)

В следующем предположениичто существуют пробелы в виде разделителей тысяч и запятые в виде десятичных дробей, кроме 1а, в котором запятые принимаются только в качестве десятичных дробей.

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класс сверху для преобразования Saldo в df:

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) Это также работает и использует только *Функция 1038 * сверху, но не класс 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")
...