【问题标题】:how to generate new columns using double loops for rows and columns in r如何使用双循环为r中的行和列生成新列
【发布时间】:2021-04-14 14:05:37
【问题描述】:

我正在根据我的数据 test_dat 创建一个 10 年的预测表。

dput(test_dat)
structure(list(hirepct = c(0, 0.0555555555555556, 0.0329218106995885, 
1.92592592592593, 0.670212765957447), prompct = c(NA, 0, 0.00823045267489712, 
2.2962962962963, 0.0500483558994197), exitpct = c(0, 0.0555555555555556, 
0.0507544581618656, 1.80246913580247, 0.703094777562863), grpcount = c(7, 
36, 729, 81, 4136), year1 = c(7, 42, 902, 298, 3793), year2 = c(7, 
49.4238683127572, 1570.21124828532, 524.623537383289, 3478.44511605416
)), row.names = c(NA, -5L), class = "data.frame")

每年都会根据公式生成行值,我已经使用 for 循环为一列生成了行:

要添加 10 年的列,我首先将列的名称创建为:year1、year2 等等:

 namevector<-c(paste0("year",seq(1:10)))

然后我正在创建 10 年的 NA 值列:

 test_dat[,namevector]<-NA

现在第 1 年我使用公式为每一行创建了值

for(i in 1:nrow(test_dat)-1){
  
  col1=test_dat[["grpcount"]][i]*(1+test_dat[["hirepct"]][i]-test_dat[["exitpct"]][i])+
    test_dat[["prompct"]][i+1]*test_dat[["grpcount"]][i+1] 
  test_dat$year1[i]<-col1
  
}
test_dat$year1[nrow(test_dat)]<-test_dat$grpcount[nrow(test_dat)]*(1+test_dat$hirepct[nrow(test_dat)]-
                                                     test_dat$exitpct[nrow(test_dat)]-
                                                     test_dat$prompct[nrow(test_dat)])

然后根据先前计算的列计算第 2 年等,因此每个新列都使用较早的列。所以我需要创建另一个循环来获得 10 列。 第 2 年列我分别计算它们:

#第 2 年

for(i in 1:nrow(test_dat)-1){
  
  col1=test_dat[["year1"]][i]*(1+test_dat[["hirepct"]][i]-test_dat[["exitpct"]][i])+
    test_dat[["prompct"]][i+1]*test_dat[["year1"]][i+1]
  test_dat$year2[i]<-col1
  
}
test_dat$year2[nrow(test_dat)]<-test_dat$year1[nrow(test_dat)]*(1+test_dat$hirepct[nrow(test_dat)]-
                                                  test_dat$exitpct[nrow(test_dat)]-
                                                  test_dat$prompct[nrow(test_dat)])

我需要一个函数来为表格创建这些列和行。

【问题讨论】:

    标签: r function loops


    【解决方案1】:

    这是一个尝试用dplyr语法重写你的计算逻辑的函数

    library(dplyr)
    
    column_1 <- paste0("year", seq(1, 10, by = 1))
    column_2 <- c("grpcount", paste0("year", seq(1, 9, by = 1)))
    
    # Column to calculate
    column_1
    #>  [1] "year1"  "year2"  "year3"  "year4"  "year5"  "year6"  "year7"  "year8" 
    #>  [9] "year9"  "year10"
    
    # Column that column_1 will be calculated based on in same order
    column_2
    #>  [1] "grpcount" "year1"    "year2"    "year3"    "year4"    "year5"   
    #>  [7] "year6"    "year7"    "year8"    "year9"
    
    # Calulate function
    calculate_year_var <- function(column_1, column_2, data) {
      data %>%
        mutate(!!sym(column_1) := if_else(row_number() == nrow(test_dat),
          !!sym(column_2)  * (1 + hirepct - exitpct - prompct),
          !!sym(column_2)  * (1 + hirepct - exitpct) +
            lead(prompct, 1) * lead(!!sym(column_2), 1)))
    }
    
    # loop through column 1 and calculate and assign back to test_dat each loop
    for (i in 1:length(column_1)) {
      test_dat <- calculate_year_var(column_1[i], column_2[i], test_dat)
    }  
    

    最终输出

    test_dat
    #>      hirepct     prompct    exitpct grpcount year1     year2     year3    year4
    #> 1 0.00000000          NA 0.00000000        7     7    7.0000    7.0000    7.000
    #> 2 0.05555556 0.000000000 0.05555556       36    42   48.0000   54.0000   60.000
    #> 3 0.03292181 0.008230453 0.05075446      729   902 1071.9150 1238.7999 1402.709
    #> 4 1.92592593 2.296296296 1.80246914       81   298  541.7901  815.6778 1123.379
    #> 5 0.67021277 0.050048356 0.70309478     4136  3793 3478.4451 3189.9764 2925.430
    #>      year5    year6    year7    year8    year9   year10
    #> 1    7.000    7.000    7.000    7.000    7.000    7.000
    #> 2   66.000   72.000   78.000   84.000   90.000   96.000
    #> 3 1563.695 1721.810 1877.106 2029.632 2179.438 2326.573
    #> 4 1469.067 1857.434 2293.747 2783.925 3334.620 3953.301
    #> 5 2682.823 2460.336 2256.299 2069.184 1897.585 1740.218
    

    reprex package (v2.0.0) 于 2021-04-14 创建

    【讨论】:

    • 我刚刚检查了它的数据正确性,解决方案正在运行,但数据直到第 1 年才正确,之后它没有给出正确的值,找不到原因
    • 找到错误来源,应该是lead(!!sym(column2), 1)而不是lead(grpcount, 1)
    【解决方案2】:

    只有在别无选择的情况下,您必须对解决方案进行矢量化并使用for。试试这个:

    library(dplyr)
    
    a <- test_dat$grpcount
    for(i in namevector){
          test_dat <- test_dat %>% mutate(
                !!sym(i) :=a*(1+hirepct-exitpct)+
                      lead(prompct,default = last(prompct))*lead(a,default = -last(a)))
          a=test_dat[,i]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-11
      • 2017-12-09
      • 2017-07-02
      相关资源
      最近更新 更多