R 如何引用函数中的列
我试图编写一个包含两个操作的函数,第一个操作包括对数据帧进行子集设置 假设我有这两个数据帧R 如何引用函数中的列,r,function,dataframe,R,Function,Dataframe,我试图编写一个包含两个操作的函数,第一个操作包括对数据帧进行子集设置 假设我有这两个数据帧 ID Var1 1 5 3 2 6 1 ID Var2 1 5 9 2 6 2 我的函数是这样的 mu_fuc = function(df, condition) { workingdf = subset(df, condition < 3) ###pass working df
ID Var1
1 5 3
2 6 1
ID Var2
1 5 9
2 6 2
我的函数是这样的
mu_fuc = function(df, condition) {
workingdf = subset(df, condition < 3)
###pass working df to the other action
}
我不知道为什么它适用于第一个函数,但不适用于第二个函数。尝试使用索引:
#Funtion
mu_fuc = function(df, condition) {
workingdf <- df[df[[condition]]<3,]
return(workingdf)
}
#Apply
mu_fuc(df1,'Var1')
使用的一些数据:
#Data
df1 <- structure(list(ID = 5:6, Var1 = c(3L, 1L)), class = "data.frame", row.names = c("1",
"2"))
#数据
df1我想你可以试试match.call
和eval
mu_fuc <- function(df, condition) {
condition <- eval(as.list(match.call())$condition, df)
workingdf <- subset(df, condition < 3)
workingdf
}
可以将条件
从简单的列引用转换为表达式,从而使函数参数包含表达式的右侧,而不是将其硬编码到函数中。这可以通过rlang
包、enquo()
和eval\u tidy()
中的几个函数来实现
我们将用一个子集函数和mtcars
数据框来说明这一点
aSubsetFunction <- function(df,condition){
require(rlang)
condition <- enquo(condition)
rows_value <- eval_tidy(condition, df)
stopifnot(is.logical(rows_value))
df[rows_value, ,drop = FALSE]
}
aSubsetFunction(mtcars,mpg > 25)
aSubsetFunction(mtcars,carb > 4)
…以及输出:
> aSubsetFunction(mtcars,mpg > 25)
Loading required package: rlang
mpg cyl disp hp drat wt qsec vs am gear carb
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
> aSubsetFunction(mtcars,carb > 4)
mpg cyl disp hp drat wt qsec vs am gear carb
Ferrari Dino 19.7 6 145 175 3.62 2.77 15.5 0 1 5 6
Maserati Bora 15.0 8 301 335 3.54 3.57 14.6 0 1 5 8
> aSubsetFunction(df1,Val1 < 3)
ID Val1
2 6 1
> aSubsetFunction(df2,Val2 < 3)
ID Val2
2 6 2
使用原始帖子中的数据,解决方案如下所示
df1 <- read.csv(text="ID,Val1
5,3
6,1")
df2 <- read.csv(text="ID,Val2
5,9
6,2")
aSubsetFunction(df1,Val1 < 3)
aSubsetFunction(df2,Val2 < 3)
结语:为什么我们不能对subset()使用变量替换?
从最初的问题来看,人们可能会认为我们可以用下面的代码来解决这个问题
mod_analysis = function(meta, moderator){
workingdf <- meta$data
moderator <- eval(as.list(match.call())$moderator, workingdf)
output = metareg(meta, moderator)
return(output)
}
subset2 <- function(df,condition){
subset(df,df[[condition]] > 4)
}
subset2(mtcars,carb)
再次提供解释,直接引用subset()
的文档
这是一个便于交互使用的功能。对于编程来说,最好使用像[]这样的标准子集函数,尤其是参数子集的非标准求值可能会产生意想不到的结果
底线:在编写函数以自动化分析时,理解Base R非标准求值非常重要,因为编码到各种R函数中的假设可能会产生意外的结果。对于依赖公式()的建模函数,如lm()
,尤其如此
,正如Wickham在中所述
参考资料:,答案很好,解释得很好,请向上投票,+1!感谢您的详细解释和示例。但是,如果我想引用另一个函数中不是子集的列,我想知道这是否可行?因此,例如,在这里,我尝试先根据条件进行子集,然后输入新的数据F使用“条件”(即列名)将rame转换为另一个函数@Chen Wei-为了直接回应您的评论,我需要看一个您试图实现的示例。但是,一般来说,如果您只需要向函数传递一个列名,则不需要我发布的面向表达式的解决方案。相反,只需将列名作为参数传递,并使用[
或[[
提取运算符的形式,以在函数中引用它。您好,我正在尝试使用您提供的链接中出现的类似内容。我正在尝试使用函数“metareg”在我自己的函数内部,但我无法让内部函数捕获它需要捕获的内容。因此,例如,我希望它捕获数据帧中一个名为“n”的列,并将其用于元回归。我尝试通过以下代码来实现这一点,但没有成功:mod_analysis=function(meta,condition,env=caller_env()){workingdf嗨,你能在原始帖子中查看更新的问题吗?谢谢!
> aSubsetFunction(mtcars,mpg > 25)
Loading required package: rlang
mpg cyl disp hp drat wt qsec vs am gear carb
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
> aSubsetFunction(mtcars,carb > 4)
mpg cyl disp hp drat wt qsec vs am gear carb
Ferrari Dino 19.7 6 145 175 3.62 2.77 15.5 0 1 5 6
Maserati Bora 15.0 8 301 335 3.54 3.57 14.6 0 1 5 8
df1 <- read.csv(text="ID,Val1
5,3
6,1")
df2 <- read.csv(text="ID,Val2
5,9
6,2")
aSubsetFunction(df1,Val1 < 3)
aSubsetFunction(df2,Val2 < 3)
> aSubsetFunction(df1,Val1 < 3)
ID Val1
2 6 1
> aSubsetFunction(df2,Val2 < 3)
ID Val2
2 6 2
aSubsetFunction <- function(df,condition){
require(rlang)
df[eval_tidy(enquo(condition), df), ,drop = FALSE]
}
> aSubsetFunction(mtcars,mpg > 25)
Loading required package: rlang
mpg cyl disp hp drat wt qsec vs am gear carb
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
> aSubsetFunction(mtcars,carb > 4)
mpg cyl disp hp drat wt qsec vs am gear carb
Ferrari Dino 19.7 6 145 175 3.62 2.77 15.5 0 1 5 6
Maserati Bora 15.0 8 301 335 3.54 3.57 14.6 0 1 5 8
>
subset2 <- function(df,condition){
subset(df,df[[condition]] > 4)
}
subset2(mtcars,carb)
Error in (function(x, i, exact) if (is.matrix(i)) as.matrix(x)[[i]] else .subset2(x, :
object 'carb' not found