在 R 中多次循环后填充数据帧
Filling a data-frame after multiple loops in R
我正在进行多个循环,我想创建一个具有不同结果的数据框。
一个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)
如果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 创建
purrr
的 pmap
和 dplyr
的 mutate
的可能解决方案如下。在这里,您可以将 my_function
替换为您想要完成的任何内容。请注意,pmap_dbl
期望 return 是一个双精度值,但您也可以使用 pmap
,然后 return 是一个列表。
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
,您可以订购它,这样您就有了原始订单。
我找到了另一个非常直观的解决方案:
首先按照@kath 的建议定义一个通用函数,它将要循环的参数作为输入:
my_function <- function(theta, rho, debt) {
kss <- (theta + rho + debt)
}
那么请求的dataframe可以构造如下:
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
>
我正在进行多个循环,我想创建一个具有不同结果的数据框。
一个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)
如果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 创建purrr
的 pmap
和 dplyr
的 mutate
的可能解决方案如下。在这里,您可以将 my_function
替换为您想要完成的任何内容。请注意,pmap_dbl
期望 return 是一个双精度值,但您也可以使用 pmap
,然后 return 是一个列表。
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
,您可以订购它,这样您就有了原始订单。
我找到了另一个非常直观的解决方案:
首先按照@kath 的建议定义一个通用函数,它将要循环的参数作为输入:
my_function <- function(theta, rho, debt) {
kss <- (theta + rho + debt)
}
那么请求的dataframe可以构造如下:
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
>