Передача списка имен переменных в пользовательскую функцию с помощью mutate - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь выполнить функцию для каждой строки и создать новый столбец, который рассматривает несколько столбцов, используя tidyverse, я изначально использовал rowwise(), но это было очень медленно. Я хочу, чтобы список столбцов в моей пользовательской функции был переменной, но я не могу заставить его работать, пока я не перечислю имена переменных явно. Например, это работает:

low_risk_codes <- c(0,1,10)
vars <- c("V1", "V2")
m <- matrix(1:9, ncol=3)
classify_low_risk_drug <- function(...){
  t <- cbind(...)
  return(apply(t, 1, function(x) ifelse(any(x %in% low_risk_codes), 1, 0)))
}

as.data.frame(m) %>%
  mutate(val4 = classify_low_risk_drug(V1, V2))

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

as.data.frame(m) %>% 
  mutate(val4 = classify_low_risk_drug(vars))

Но я не могу заставить его работать, даже если я включай !!, что мне не хватает ?!

Также приветствуются любые предложения о том, как сделать это с помощью map!

1 Ответ

0 голосов
/ 14 февраля 2020

Звучит так, будто это будет делать то, что вы хотите, но мне нужно это квалифицировать (много). Во-первых, к вашему сведению, я все еще сосредотачиваюсь на NSE в R, но считаю эту виньетку очень полезной.

В связи с решением я попытался ускорить функцию, избегая rowwise() или apply(). Это должно быть быстрее с rapply() / rowSums(), но я не тестировал его. Это может привести к проблемам с очень большими данными, потому что rowSums() преобразует кадр данных в матрицу, но это, вероятно, не будет проблемой. Теоретически, вы также должны иметь возможность использовать выбранные хелперы / имена кавычек без кавычек / позиции столбцов (если вы решитесь).

Кроме того, я нахожу немного странным то, что вам нужно предоставить кадр данных в качестве первого аргумент (то есть, как .), но может быть способ обойти это. Я, конечно, открыт для любого, кто хочет отредактировать это / использовать это как основу для своего решения. Надеюсь, что это поможет / поможет вам двигаться в правильном направлении!

classify_low_risk_drug <- function(.data, vars, codes, na.rm = FALSE){

  df <- rapply(.data, function(x) x %in% codes, how = "replace")
  as.integer(rowSums(select(df, !!enquo(vars)), na.rm = na.rm) > 0)

  }

as.data.frame(m) %>%
  mutate(val4 = classify_low_risk_drug(., vars = vars, codes = c(0, 1, 10)))
  V1 V2 V3 val4
1  1  4  7    1
2  2  5  8    0
3  3  6  9    0

РЕДАКТИРОВАТЬ: вы могли бы немного улучшить скорость, избегая преобразования матрицы / используя lapply() w / pmax():

classify_low_risk_drug2 <- function(.data, vars, codes, na.rm = FALSE){

  as.integer(do.call(pmax, lapply(select(.data, !!enquo(vars)), `%in%`, codes)))

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