我想编写一个函数,该函数可以将数据框内的列或列名以及它们来自的数据框作为参数。
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
这是怎么回事?
谢谢!
答案 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)
。