映射多个参数,其中一个参数是常量(数据)

时间:2019-06-04 12:27:35

标签: r mapply

我正在努力在构造函数的地方使用mapply,因为我在一个较大的环境中进行编程,例如,如果我编写的函数中其中一个参数是 data,则我需要一个或多个参数

fun_test <- function(data,col,val1,val2){return(data[col][1,] * val1-val2)}

因此 data col 可以是恒定的,但是我想根据 val1 val2 :

> mapply(FUN=fun_test,mtcars,"cyl",mtcars$cyl,mtcars$cyl*2)
Error in data[col][1, ] : incorrect number of dimensions

我试图了解mapply的工作方式;我肯定不能通过mtcars,而将“ cyl”作为矢量传递,可以吗?

编辑:我的环境中的数据可能会有所不同,例如有时我使用mtcars,有时是另一个数据集。所以我不能将数据硬编码到函数中

EDIT2 : 1)我有一些数据集的数据, 2)我有一些读入R的Excel文件, 3)我做了一个查找功能,从R中的这些Excel文件中提取信息, 4)进入我创建的查找功能并提取信息时的一个或两个变量(来自数据集)。

因此,这些查找功能取决于数据(我需要查找的变量)和用于查找的Excel文件。

2 个答案:

答案 0 :(得分:2)

mapply是多维lapply。这意味着,它不仅要遍历一个对象(即data.frame的列或向量的元素),还要同时遍历多个对象。唯一的条件是这些对象的长度必须相同,即data.frame的列和矢量的长度。因此,您不能传递常量(除非您传递具有相同常量的向量以匹配长度,但是为什么要这样做)。

尝试一个简单的例子(将向量的索引加起来):

mapply(sum, 1:10, 11:20)

因此,在您的情况下,只需将常量直接传递给函数即可:

fun_test <- function(val1, val2){return(mtcars['cyl'] * val1 - val2)}

mapply(FUN=fun_test, mtcars$cyl, mtcars$cyl*2)

更新

然后,我认为您需要在函数中包含mapply。这样,您可以添加任何您喜欢的参数(常量和变量)。看起来像这样:

myfunc <- function(data, col, val1, val2) {

  fun_test <- function(val1, val2) {
    data[col] * val1 - val2 
  }

  mapply(FUN=fun_test, val1, val2)

}

myfunc(mtcars, 'cyl', mtcars$cyl, mtcars$cyl*2)

答案 1 :(得分:1)

如果您想将数据帧作为常量值传递,则将其作为列表传递,以便将其完全回收,否则它将分别传递mapply中的每一列

fun_test <- function(data,col,val1,val2){return(data[1, col] * val1-val2)}

mapply(FUN=fun_test, list(mtcars),"cyl",mtcars$cyl,mtcars$cyl*2)
#[1] 24 24 16 24 32 24 32 16 16 24 24 ......

因此输出中的第一个值24可以由

重现。
mtcars[1, "cyl"] * mtcars$cyl[1] - mtcars$cyl[1]*2
#[1] 24

我知道这是一个示例,实际的实现方式有所不同,但是您可以直接通过这样做获得相同的输出

mtcars[1, "cyl"] * mtcars$cyl - mtcars$cyl*2

要了解这两个调用之间的区别,我们可以调试函数,在函数中添加browser()

fun_test <- function(data,col,val1,val2){
   browser()
   return(data[1, col] * val1-val2)
}

现在,调用函数并检查函数中的参数

mapply(FUN=fun_test, mtcars,"cyl",mtcars$cyl,mtcars$cyl*2)
Browse[1]> data
# [1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 
#     10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 
#     15.8 19.7 15.0 21.4

这是mtcars中的第一列,即mpg(选中mtcars$mpg)。

这是一个数字矢量,现在您尝试对mpg列和索引1进行子集设置,这会给您带来相同的错误

mtcars$mpg["cyl"][1, ]
  

mtcars $ mpg [“ cyl”] [1,]中的错误:维数不正确

现在在第二种情况下,当我们将数据帧作为列表传递时,请选中data

 mapply(FUN=fun_test, list(mtcars),"cyl",mtcars$cyl,mtcars$cyl*2)

Browse[1]> data
#                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#Mazda RX4           21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#Mazda RX4 Wag       21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#Datsun 710          22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#Hornet 4 Drive      21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#Hornet Sportabout   18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
#Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#....

这是完整的数据框,然后您可以从中进行子集

>data[1, "cyl"]
#[1] 6

PS-我不知道为什么要这么做的上下文,我相信会有更好的方法来处理它。