我正在执行多个循环,我想创建一个具有不同结果的数据框。
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
值并创建一个数据框,该数据框本质上应在一个易于理解的数据框中汇总所有可能的(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)
答案 0 :(得分:1)
如果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(v0.2.1)于2019-03-17创建
答案 1 :(得分:1)
使用/application
中的pmap
和purrr
中的mutate
的一种可能的解决方案如下。在这里,您可以将dplyr
替换为您要完成的所有操作。请注意,my_function
期望返回一个双精度数,但是您也可以使用pmap_dbl
来返回一个列表。
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
替换您指定的循环。它采用一个函数并将其应用于data.frame pmap
的每一行,并使用列表中指定的参数作为该函数的参数。
使用my.df
,可以订购原始订单。
答案 2 :(得分:0)
我找到了另一个非常直观的解决方案:
首先,@ 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
>