Reputation: 640
I want to run a function and extract outputs for objects within the function. The output I am expecting is a dataframe with 5 rows and 5 columns. Instead, I obtain a 1000 rows with 5 columns.
Here is the code with reproducible example:
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
My understanding is that the last column of the results3
object should be a single value coming from resultP
. However, it looks like I am getting the whole P
vector (last column of output) that I am using as input. I am probably doing something wrong with the (m)apply function for which I am not very familiar.
Any hint will be appreciated.
Thanks.
Upvotes: 0
Views: 135
Reputation: 1367
By passing P as an argument to mapply
you are iterating over it and recycling your shorter variables. Two ways around this depending on how you are planing on putting this to use, you could either take P out of both your argument list and the call to mapply
, or you can create a list that repeats P once for each iteration though.
The first approach, change your function definition by removing "P" from the argument list:
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
This approach depends on P being defined outside of the function. If you are calling with different P vectors you would need to reassign P outside of the function before each run.
The second approach would be more versatile and allow you to use other vectors for P in different runs.
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
Upvotes: 1