У меня есть четыре функции: clean, clean2, cleanFun и trim. В настоящее время я применяю функции к одному столбцу, вот так.

library(tidyverse)
library(data.table)


py17$CE.Finding.Description <- clean(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- clean2(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- cleanFun(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- trim(py17$CE.Finding.Description)

Этот процесс делает свое дело, но мне нужно скопировать и вставить его несколько раз, и в конечном итоге я хотел бы расширить его до нескольких столбцов.

На данный момент я хотел бы сэкономить время и добавить функцию применения, но я не уверен, как создать эту функцию применения. Я пробовал создать это.

maxclean <- function(cleaner) {
                c(clean(cleaner), clean2(cleaner), cleanFun(cleaner), trim(cleaner))
                 }


py17$CE.Finding.Description <- sapply(py17$CE.Finding.Description, maxclean)

Попробовав это, я просто получаю

Error in `$<-.data.frame`(`*tmp*`, CE.Finding.Description, value = c(NA,  : 
  replacement has 4 rows, data has 4318

При этом я не получаю никаких ошибок. Где я ошибаюсь в этом?

0
Roy 8 Окт 2018 в 16:27

2 ответа

Лучший ответ

Ваша функция maxclean должна принимать те же аргументы, что и отдельные функции. В вашем случае - вектор. А затем вызовите каждую функцию подряд. Как это:

maxclean <- function(x) {
            x <- clean(x)
            x <- clean2(x)
            x <- cleanFun(x)
            x <- trim(x)
            return(x)
            }
3
Karolis Koncevičius 8 Окт 2018 в 13:31

По-видимому, OP создал конвейер очистки, где выходные данные одного шага передаются на следующий шаг, а конечный результат конвейера перезаписывает исходный вход.

В пакете magrittr есть функция freduce(), которая применяет одну функцию за другой описанным способом. Таким образом ,

py17$CE.Finding.Description <- clean(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- clean2(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- cleanFun(py17$CE.Finding.Description)
py17$CE.Finding.Description  <- trim(py17$CE.Finding.Description)

Можно записать как:

library(magrittr)
fcts <- list(clean, clean2, cleanFun, trim)
py17$CE.Finding.Description %<>% freduce(fcts)

Который является ярлыком для

py17$CE.Finding.Description <- py17$CE.Finding.Description %>% 
  clean() %>% 
  clean2() %>% 
  cleanFun() %>% 
  trim()

Здесь %>% - это оператор прямой линии magrittr, а %<>% - оператор конвейерной линии составного назначения magrittr, который обновляет левый объект с полученным значением.

Воспроизводимый пример

Используя набор данных mtcars:

data(mtcars)
mycars <- mtcars
mycars$mpg %<>% 
  {. - mean(.)} %>% 
  abs() %>% 
  sqrt()
mycars

Или

mycars <- mtcars
mycars$mpg %<>% freduce(list(function(.) {. - mean(.)}, abs, sqrt))
mycars

Применение к нескольким столбцам

OP упомянул, что он в конечном итоге хотел бы расширить это до нескольких столбцов

Этого можно достичь, например,

mycars <- mtcars
fcts <- list(function(.) {. - mean(.)}, abs, sqrt)
mycars$mpg %<>% freduce(fcts)
mycars$disp %<>% freduce(fcts)
mycars
0
Uwe 24 Дек 2019 в 02:43