在R中的多个循环之后填充数据帧

问题描述 投票:-1回答:3

我正在做多个循环,我想创建一个具有不同结果的数据帧。

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)
    }
  }
} 

我想在每个迭代存储中使用kssvalues并创建一个数据帧,该数据帧应该在一个简单易懂的数据帧中概括所有可能的(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)
r loops dataframe for-loop fill
3个回答
1
投票

来自pmappurrr和来自mutatedplyr的一种可能的解决方案如下。在这里你可以用你想要完成的任何东西取代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,您可以订购它,以便您拥有原始订单。


1
投票

如果kss只是debtrhotheta的总和,它可以很容易地完成:

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)


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
> 
© www.soinside.com 2019 - 2024. All rights reserved.