дружественная к dplyr пользовательская функция для использования с функциями соединения - PullRequest
0 голосов
/ 21 февраля 2019

Работа, которую я выполняю, включает в себя объединение нескольких баз данных из разных источников по ключевой переменной поиска.Переменная является строковой переменной и часто пишется по-разному в зависимости от источника данных (например, «Нью-Йорк Сити», «Сити Нью-Йорк»).

Я написал простую функцию для очистки переменных поиска в каждом наборе данных и использую ее следующим образом:

clean.names <- function(x){
  x %>% 
    str_remove_all('[:punct:]') %>% 
    str_to_lower() %>% 
    str_squish() %>% 
    str_trim()
}

#df_1 and df_2 are dataframes, with variables key that I use to merge. 
df_1 %>% 
  mutate(clean_name = clean.names(key1)) %>% 
  left_join(df_2 %>% 
              mutate(clean_name = clean.names(key2)), 
            by = 'clean_name')

Эта функция довольно хорошо работает для того, для чего она предназначена,Однако код немного многословен.Мой вопрос: как я могу создать функцию, которая работает с dplyr (т.е. без кавычек и т. Д.), Которая производит тот же эффект, что и выше?Мне бы хотелось, чтобы он был в истинной форме dplyr и работал в качестве оболочки в функциях соединения.Я попробовал свои силы в этом безуспешно, см. Здесь:

clean.names <- function(x =df, y = merge.vary){ # function adds
  x$merge.vary <- y %>%                         # a new variable
    str_remove_all('[:punct:]') %>%             # to existing dataframe
    str_to_lower() %>% 
    str_squish() %>% 
    str_trim()
}


clean.names(df_1, key1) %>%         # then use the function as a wrapper
  left_join(clean.names(df_2, key2))# for the dplyr join functions 

Есть ли способ сделать это?Я хотел бы иметь действующую функцию dplyr-esque, которая выглядит следующим образом: function (dataframe, variable).Спасибо.

1 Ответ

0 голосов
/ 21 февраля 2019

Вы можете использовать rlang::ensym(), чтобы захватить имя переменной и передать ее непосредственно mutate_at:

library(tidyverse)
clean.names2 <- function( .df, .var ) {
  f <- compose( partial(str_remove_all, pattern='[:punct:]'), 
                 str_to_lower, str_squish, str_trim )
  .df %>% mutate_at( vars(!!ensym(.var)), f )
}

Функция работает с именами переменных, предоставленными и без кавычек:

X <- tibble( Cities = c("  New York City, NY", "Denver, CO;;") )
clean.names2( X, Cities )
# # A tibble: 2 x 1
#   Cities          
#   <chr>           
# 1 new york city ny
# 2 denver co       

clean.names2( X, "Cities" )  ## equivalent

Краткое объяснение:

В первой строке создается составная функция путем объединения вместе str_remove_all, str_to_lower, str_squish, str_trim и использования partial() для назначениязаданное значение для параметра pattern, равное str_remove_all.Полученная функция f идентична вашей исходной clean.names.(Я только что попытался сделать clean.names2 автономным.)

Вторая строка применяет новую составную функцию f (или, что эквивалентно, ваш исходный clean.names) к одному столбцу в .df, используяmutate_at.Столбец указывается с использованием двух механизмов обратного хода.Первый - vars(), который позволяет пользователям указывать имена столбцов с кавычками и без них.Например, следующие две строки эквивалентны:

mydf %>% mutate_at( vars("mycolumn"), myfunction )  # vars can be dropped here
mydf %>% mutate_at( vars(mycolumn), myfunction )

Второй механизм принадлежит классу функций, которые имеют дело с квазикватацией , позволяя программистам работать напрямую с неоцененными выражениями, в том числепредоставляемые пользователями функции.В частности, мы используем ensym для захвата символа, предоставленного функции вызывающей средой, и передачи этого символа в vars.!! важен, потому что он говорит vars идти вперед и оценить выражение ensym(.var) и использовать результат в качестве имени столбца.Без !!, vars будет пытаться найти столбец с именем «ensym (.var)».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...