r Аргументы пользовательских функций - что можно определить в качестве аргумента? - PullRequest
2 голосов
/ 21 февраля 2020

Я пытаюсь написать функции R, которые выполняют те же задачи, что и макросы в SAS, такие как

  1. переменные процесса
  2. имя новой переменной
  3. имя новый фрейм данных

Я пробовал некоторые основные функции c, используя встроенные df "iris" и dplyr, как показано ниже.

Функции f3 и f4 пытаются взять имя переменной и обработать ее. сообщения об ошибках: «Ошибка: объект« Виды »не найдены» и «В смысле. по умолчанию (var): аргумент не числовой c или логический: возвращающий NA».

Функции f5 и f6 пытаются назвать новую переменную или новую df. После запуска функции новой переменной или df было присвоено имя в качестве аргумента.

f7 попытался присвоить части переменной имя с помощью функции.

library(dplyr)

data(iris)
view(iris)

### Char Variable
f3 <- function(var){
      iris %>% filter(var == "setosa")
}
f3(Species)

f4 <- function(var){
      iris %>% summarise(
            avg = mean(var)
      )
}
f4("Sepal.Length")

### Variable Name
f5 <- function(name){
      iris %>% 
            mutate(name = 1)
}
f5("newname")

### df Name
f6 <- function(dfname){
      dfname <- iris 
}
f6("newdf")

f7 <- function(name){
      test <- iris %>% 
            mutate(
                  v_name = 1
            )
}
f7("1")

1 Ответ

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

С помощью tidyverse, если мы передадим без кавычек, его можно преобразовать в выражение (rlang::enquo) и вычислить (!!), что выполняется с помощью оператора {{}} curly-curly

f3 <- function(var){
  iris %>%
       filter({{var}} == "setosa")
 }
f3(Species)
#    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1           5.1         3.5          1.4         0.2  setosa
#2           4.9         3.0          1.4         0.2  setosa
#3           4.7         3.2          1.3         0.2  setosa
#4           4.6         3.1          1.5         0.2  setosa
#5           5.0         3.6          1.4         0.2  setosa
#...

f4 также может быть сделано с тем же для без кавычек

f4 <- function(var){
  iris %>% 
      summarise(
        avg = mean({{var}})
      )
   }

f4(Sepal.Length)
#     avg
#1 5.843333

Если намерение состоит в том, чтобы передать либо в кавычки или без кавычек, преобразовать в символ с ensym и оценить (!!)

 f4 <- function(var){
  iris %>% 
    summarise(
        avg = mean(!! rlang::ensym(var))
   )
 }
 f4(Sepal.Length)
 #       avg
 #1 5.843333
 f4("Sepal.Length")
 #     avg
 #1 5.843333

Для f7 мы можем использовать :=

library(stringr)
f7 <- function(name){
  iris %>% 
        mutate(
              !!str_c("v_", name) := 1
        )
 }

f7("1")
#      Sepal.Length Sepal.Width Petal.Length Petal.Width    Species v_1
#1            5.1         3.5          1.4         0.2     setosa   1
#2            4.9         3.0          1.4         0.2     setosa   1
#3            4.7         3.2          1.3         0.2     setosa   1
#4            4.6         3.1          1.5         0.2     setosa   1
#...

Или с f5

f5 <- function(name){
  iris %>% 
        mutate(!! name := 1)
 }
f5("newname")
#     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species newname
#1            5.1         3.5          1.4         0.2     setosa       1
#2            4.9         3.0          1.4         0.2     setosa       1
#3            4.7         3.2          1.3         0.2     setosa       1
#4            4.6         3.1          1.5         0.2     setosa       1
# ..

ПРИМЕЧАНИЕ: Если мы сделаем <- как последний оператор возврата, его нужно будет либо присвоить объекту, либо обернуть с помощью () для вывода на печать, т. Е. (f5("newname"))

f6 означает assign объект, и это можно сделать с помощью assign

f6 <- function(dfname){
   assign(dfname, value = iris, envir = .GlobalEnv) 
 }
f6("newdf")
head(newdf, 2)
#  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1          5.1         3.5          1.4         0.2  setosa
#2          4.9         3.0          1.4         0.2  setosa
...