当 运行 R 中的函数使用 mapply 时,我观察到的输出不是我期望的

When running a function in R using mapply, the output I observe is not why I expected

我想 运行 一个函数并提取函数内对象的输出。我期望的输出是一个包含 5 行和 5 列的数据框。相反,我获得了 1000 行和 5 列。

这是具有可重现示例的代码:

input.rows3 <- data.frame(pd=c(38, 50, 50, 86, 38),
                          Cl=c(15, 40, 30, 81, 15),
                          va=c(150, 145, 160, 141, 150),
                          co=c(3.0, 4.5, 4.0, 4.8, 1.5))

P <- c(seq(0,184,length.out=1000))

deriv.model <- function(a,b,c,x){
        (a*exp(-((((exp(b)*x))/1000))+c+b))/1000
}

marg.N.resp.function3 <- function(va, co, pd, Cl, P){
        a <-  10000  + 20*Cl
        b <- 2
        c <- (-0.05*pd)
        pr <- co / (va/1000)
        optimalP <- as.data.frame(deriv.model(a,b,c,P)) %>% 
                rename(optimalP = "deriv.model(a, b, c, P)") %>% 
                mutate(diff=abs(optimalP - pr))
        resultP <-cbind(optimalP,P) %>%
                slice(which.min(diff)) %>% 
                select(P)
        newlist <- list(a, b, c, pr, resultP)
        return(newlist)

}

results3 <- as.data.frame(t(mapply(marg.N.resp.function3, 
                                   input.rows3$va, 
                                   input.rows3$co, 
                                   input.rows3$pd,
                                   input.rows3$Cl,
                                   P))) 

results3

我的理解是 results3 对象的最后一列应该是来自 resultP 的单个值。但是,看起来我得到了我用作输入的整个 P 向量(输出的最后一列)。我可能对我不太熟悉的 (m)apply 函数做错了什么。

如有任何提示,我们将不胜感激。

谢谢。

通过将 P 作为参数传递给 mapply,您正在迭代它并回收较短的变量。有两种解决方法,具体取决于您打算如何使用它,您可以从参数列表和对 mapply 的调用中取出 P,或者您可以创建一个列表,在每次迭代中重复 P 一次不过

第一种方法,通过从参数列表中删除 "P" 来更改函数定义:

library(tidyverse) # for %>%

marg.N.resp.function4 <- function(va, co, pd, Cl){
      a <-  10000  + 20*Cl
      b <- 2
      c <- (-0.05*pd)
      pr <- co / (va/1000)
      optimalP <- as.data.frame(deriv.model(a,b,c,P)) %>% 
            rename(optimalP = "deriv.model(a, b, c, P)") %>% 
            mutate(diff=abs(optimalP - pr))
      resultP <-cbind(optimalP,P) %>%
            slice(which.min(diff)) %>% 
            select(P)
      newlist <- list(a, b, c, pr, resultP)
      return(newlist)

}



results4 <- as.data.frame(t(mapply(marg.N.resp.function4, 
                                   input.rows3$va, 
                                   input.rows3$co, 
                                   input.rows3$pd,
                                   input.rows3$Cl 

                                   ))) 

results4

# V1 V2   V3       V4      V5
# 1 10300  2 -1.9       20       0
# 2 10800  2 -2.5 31.03448       0
# 3 10600  2 -2.5       25       0
# 4 11620  2 -4.3 34.04255       0
# 5 10300  2 -1.9       10 17.4975

此方法取决于 P 在函数外部定义。如果您使用不同的 P 向量进行调用,则需要在每个 运行.

之前在函数外部重新分配 P

第二种方法更通用,允许您在不同的 运行 中为 P 使用其他向量。

results3 <- as.data.frame(t(mapply(marg.N.resp.function3, 
                                   input.rows3$va, 
                                   input.rows3$co, 
                                   input.rows3$pd,
                                   input.rows3$Cl,
                                   list(rep(P, times = 5))

))) 

results3
# V1 V2   V3       V4      V5
# 1 10300  2 -1.9       20       0
# 2 10800  2 -2.5 31.03448       0
# 3 10600  2 -2.5       25       0
# 4 11620  2 -4.3 34.04255       0
# 5 10300  2 -1.9       10 17.4975

identical(results4, results3)
# [1] TRUE