Написание функций с аргументом «data» - PullRequest
1 голос
/ 29 апреля 2019

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

df <- data.frame(x = c(1:5), y = c(6:10), z = LETTERS[1:5])

my_fxn <- function (aaa, bbb, ccc, data) {
  if (!missing(data)) {
    aaa = as.numeric(data$aaa)
  }
  print(aaa[1])
}

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

> my_fxn(df$x, df$y, df$z, df)
[1] 1

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

> my_fxn(x, y, z, df)
[1] NA

Однако, работают, когда имена столбцов и имя фрейма данных совпадают с именами аргументов функции:

data <- df
names(data) <- c("aaa", "bbb", "ccc")
> my_fxn(aaa, bbb, ccc, data)
[1] 1

Что происходит?

Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 апреля 2019

В некотором роде от Cettt - что-то вроде этого может быть тем, что вы ищете:

df <- data.frame(x = c(1:5), y = c(6:10), z = LETTERS[1:5])

my_fxn <- function (aaa, bbb, ccc, data) {
  if (!missing(data)) {
    aaa = as.numeric(data[[aaa]])
    bbb = as.numeric(data[[bbb]])
    ccc = as.character(data[[ccc]])
  }
  print(aaa[1])
}

my_fxn("x", "y", "z", df)
#> [1] 1

При использовании enquo() из library(dplyr) нам больше не нужно вводить символы в качестве переменных функции:

library(dplyr)

my_fxn <- function (aaa, bbb, ccc, data) {
  aaa <- enquo(aaa)
  bbb <- enquo(bbb)
  ccc <- enquo(ccc)

  if (!missing(data)) {
    aaa = as.numeric(pull(data, !!aaa))
    bbb = as.numeric(pull(data, !!bbb))
    ccc = as.character(pull(data, !!ccc))
  }
  print(aaa[1])
}

my_fxn(x, y, z, df)
#> [1] 1

Более подробную информацию о построении функций с enquo() и !! можно найти здесь: https://dplyr.tidyverse.org/articles/programming.html#programming-recipes


Наконец, решение base R с использованием deparse() и substitute():

my_fxn <- function (aaa, bbb, ccc, data) {
  aaa <- deparse(substitute(aaa))
  bbb <- deparse(substitute(bbb))
  ccc <- deparse(substitute(ccc))

  if (!missing(data)) {
    aaa = as.numeric(data[[aaa]])
    bbb = as.numeric(data[[bbb]])
    ccc = as.character(data[[ccc]])
  }
  print(aaa[1])
}

my_fxn(x, y, z, df)
#> [1] 1
0 голосов
/ 29 апреля 2019

Проблема в том, что при вызове my_fxn(x, y, z, df) объект x не определяется.Следовательно, df$x возвращает не столбец x, а NA.

. Рассмотрим небольшой пример:

df <- data.frame(x = 1:3, y = 4:6)
x <- "y"
df$x # returns column x
[1] 1 2 3
df[,x] #returns column y since the value which is stored in x is "y"
[1] 4 5 6

Чтобы обойти вашу проблему, вы можете использовать data[, aaa] вместо data$aaa.Еще одной альтернативой может быть использование пакета dplyr, в котором вы можете использовать select(data, aaa).

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