R语言中使用mapply处理带向量参数的函数时遇到问题
解决
mapply调用自定义函数时的参数传递问题 我懂你的困扰啦——你写的foo函数单独调用时完全正常,但用mapply批量调用时,没法正确给y参数传入向量类型的输入对吧?别着急,咱们一步步来解决。
先回顾你的函数与测试表现
你的函数定义
foo <- function(x, y){ if(length(y)==1){ return(x*y) } else{ return(x - y[1]*y[2]) } }
这个函数设计得很灵活:当y是单个数值时返回x*y,当y是长度为2的向量时返回x减去y两个元素的乘积。
单独调用的测试结果
> # test function: > foo(1,2) [1] 2 > foo(1,c(1,2)) [1] -1
单独调用完全符合预期,问题出在mapply的参数传递逻辑上。
问题根源与解决方案
mapply的默认行为是把传入的向量拆成单个元素逐个传递给函数参数,但你需要让部分y参数接收的是完整的向量,这就需要我们改变参数的传递方式:把每个要作为整体传入的向量包装成列表的一个元素。
假设你的数据框是这样的(补全你未写完的代码)
df <- data.frame( a = floor(runif(6, 1,10)), b = floor(runif(6, 18,80)), c = floor(runif(6, 1,80)), d = floor(runif(6, 1,10)) )
场景1:混合传入单个值与向量给y
比如你想让前3次调用的y用df$b的单个数值,后3次用df$c和df$d组成的向量:
# 先构造y的输入列表:前3个是单个值,后3个是完整向量 y_inputs <- c( as.list(df$b[1:3]), # 单个值转成列表元素 mapply(function(c_val, d_val) c(c_val, d_val), df$c[4:6], df$d[4:6], SIMPLIFY = FALSE) # 生成向量列表 ) # 用mapply调用foo,此时每个y_inputs的元素会完整传给y参数 results <- mapply(foo, x = df$a, y = y_inputs, SIMPLIFY = FALSE) # 如果需要把结果转成向量,用unlist()即可 unlist(results)
场景2:所有y都传入两列组成的向量
如果你的需求是每一行都用df$c和df$d组成的向量作为y,和df$a的x配对调用:
# 把每一行的c和d打包成向量,作为列表元素 y_vectors <- mapply(c, df$c, df$d, SIMPLIFY = FALSE) # 调用foo,此时每个向量都会完整传入y参数 results <- mapply(foo, x = df$a, y = y_vectors, SIMPLIFY = FALSE) unlist(results)
核心逻辑就是:mapply只会把列表的每个元素作为完整参数传递,而向量会被拆分成单个元素,所以只要把需要整体传入的向量包装成列表的元素,就能解决你的问题啦。
内容的提问来源于stack exchange,提问作者Helen
相关产品推荐
相关产品推荐

