我正在做多个循环,我想创建一个具有不同结果的数据帧。
MWE如下:
# define cases
debt <-c(0,0.05)
thetas <- c(1, 1.5)
rhos <- c(0, 0.99, 2) # 0:C-D case, 1 = linear (no effect on prices)%
然后想循环上面的向量
for (theta in thetas){
for (rho in rhos){
for (b in debt) {
sols <-nleqslv(0.05, k_ss) # k_ss is defined in the end
kss <-round(sols$x,5)
}
}
}
我想在每个迭代存储中使用kss
values并创建一个数据帧,该数据帧应该在一个简单易懂的数据帧中概括所有可能的(i.e. length(theta)*length(rho)*length(debt) = 12 in this example)
组合。
我的预期结果应如下所示:
thetas <- c(1, 1.5)
rhos <- c(0,0.99, 2) # 0:C-D case, 1 = linear (no effect on prices)%
debts <-c(0,0.05)
n = length(debt)*length(thetas)*length(rhos)
theta<-c(rep(1,6),rep(1.5,6))
rho <-c(rep(0,2),rep(0.99,2), rep(2,2), rep(0,2),rep(0.99,2), rep(2,2))
debt <-rep(c(0,0.05),6)
kss <-rnorm(12,0,1) # suppose these are my true ('expected' kss valuesthat i get for the iterations
df <- data.frame(theta,rho,debt,kss)
df
theta rho debt kss
1 1.0 0.00 0.00 1.1090
2 1.0 0.00 0.05 1.8436
3 1.0 0.99 0.00 0.7718
4 1.0 0.99 0.05 0.5628
5 1.0 2.00 0.00 -1.1774
6 1.0 2.00 0.05 2.1973
7 1.5 0.00 0.00 0.8531
8 1.5 0.00 0.05 -0.1252
9 1.5 0.99 0.00 0.4784
10 1.5 0.99 0.05 1.8334
11 1.5 2.00 0.00 0.3693
12 1.5 2.00 0.05 1.0470
这里记录的是我的kss是如何生成的:
# compute steady state
k_ss<-function(k){
# this function is defined for given values in b, theta, rho
# all other variables not defined here are some scalars not defined here
# for simplicity
if (rho == 0){
R <- A*alpha*k^(alpha-1)
w <- A*(1-alpha)*k^(alpha)
} else{
y <-A*(alpha*k^rho + (1-alpha))^(1/rho)
R <- A*alpha*(y/A*k)^(1-rho)
w <- A*(1-alpha)*(y/A)^(1-rho)
}
kt <-nn*(dt/beta*nn)^(1/theta)
sd <-((beta*R)^(1/theta))*(1+kt)/(R+(beta*R)^(1/theta)*(1+kt))
mpb <-(1/nn)*(kt/(1+kt))
ego <-sd/(1-sd*mpb*R)
kss <-(nn)*(k+b) - (ego*(w-(R-nn)*b))
return(kss)
}
然后:
sols <-nleqslv(0.05, k_ss)
kss <-round(sols$x,5)
来自pmap
的purrr
和来自mutate
的dplyr
的一种可能的解决方案如下。在这里你可以用你想要完成的任何东西取代my_function
。请注意,pmap_dbl
希望返回一个double,但您也可以使用pmap
然后返回一个列表。
library(dplyr)
library(purrr)
theta <- c(1, 1.5)
rho <- c(0, 0.99, 2)
debt <- c(0, 0.05)
my.df <- expand.grid(theta = theta, rho = rho, debt = debt)
my_function <- function(theta, rho, debt) {
kss <- theta + rho + debt
}
my.df %>%
mutate(kss = pmap_dbl(list(theta = theta, rho = rho, debt = debt), my_function)) %>%
arrange(theta, rho, debt)
# theta rho debt kss
# 1 1.0 0.00 0.00 1.00
# 2 1.0 0.00 0.05 1.05
# 3 1.0 0.99 0.00 1.99
# 4 1.0 0.99 0.05 2.04
# 5 1.0 2.00 0.00 3.00
# 6 1.0 2.00 0.05 3.05
# 7 1.5 0.00 0.00 1.50
# 8 1.5 0.00 0.05 1.55
# 9 1.5 0.99 0.00 2.49
# 10 1.5 0.99 0.05 2.54
# 11 1.5 2.00 0.00 3.50
# 12 1.5 2.00 0.05 3.55
pmap
替换您指定的循环。它接受一个函数并将其应用于data.frame my.df
的每一行,并使用列表中指定的参数作为函数的参数。
使用arrange
,您可以订购它,以便您拥有原始订单。
如果kss
只是debt
,rho
和theta
的总和,它可以很容易地完成:
thetas <- c(1, 1.5)
rhos <- c(0, 0.99, 2)
debts <-c(0, 0.05)
df <- expand.grid(theta = thetas, rho = rhos, debt =debts)
non_linear_equation_solver <- function(theta, rho, debt) {
kss <- (theta + rho + debt) # for example
return(kss)
}
df$kss <- apply(df, 1, function(x) non_linear_equation_solver(x[1], x[2], x[3]))
df
#> theta rho debt kss
#> 1 1.0 0.00 0.00 1.00
#> 2 1.5 0.00 0.00 1.50
#> 3 1.0 0.99 0.00 1.99
#> 4 1.5 0.99 0.00 2.49
#> 5 1.0 2.00 0.00 3.00
#> 6 1.5 2.00 0.00 3.50
#> 7 1.0 0.00 0.05 1.05
#> 8 1.5 0.00 0.05 1.55
#> 9 1.0 0.99 0.05 2.04
#> 10 1.5 0.99 0.05 2.54
#> 11 1.0 2.00 0.05 3.05
#> 12 1.5 2.00 0.05 3.55
由reprex package创建于2019-03-17(v0.2.1)
我发现了另一个非常直观的解
首先,正如@kath所建议的那样,定义一个通用函数,它将一个想要循环的参数作为输入:
my_function <- function(theta, rho, debt) {
kss <- (theta + rho + debt)
}
然后可以按如下方式构造所询问的数据帧:
output<-list() # create an empty list
i <-0 # counter
for (theta in thetas){
for (rho in rhos){
for (b in debt) {
i=i+1
kss<-my_function(theta,rho,b)
output[[i]]<-data.frame(Theta = theta, Rho = rho, Debt = b, K = kss)
}
}
}
然后绑定列表中的数据帧:
df<-do.call(rbind,output)
And here is the result:
Theta Rho Debt K
1 1.0 0.00 0.00 1.00
2 1.0 0.00 0.05 1.05
3 1.0 0.99 0.00 1.99
4 1.0 0.99 0.05 2.04
5 1.0 2.00 0.00 3.00
6 1.0 2.00 0.05 3.05
7 1.5 0.00 0.00 1.50
8 1.5 0.00 0.05 1.55
9 1.5 0.99 0.00 2.49
10 1.5 0.99 0.05 2.54
11 1.5 2.00 0.00 3.50
12 1.5 2.00 0.05 3.55
>