Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 如何引用函数中的列_R_Function_Dataframe - Fatal编程技术网

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