用“数据”参数编写函数

时间:2019-04-29 13:22:43

标签: r dataframe

我想编写一个函数,该函数可以将数据框内的列或列名以及它们来自的数据框作为参数。

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])
}

当我从数据框中提供列作为参数时,此功能可以正常工作

> 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 个答案:

答案 0 :(得分:2)

要带回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


最后,是使用deparse()substitute()的基本R解决方案:

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

答案 1 :(得分:0)

问题在于,调用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)