【问题标题】:Loop to calculate weights and create new variables循环计算权重并创建新变量
【发布时间】:2018-10-28 10:49:27
【问题描述】:

如果我从以下数据集开始并调用df

   A    B
  0.8   0.9
  0.99  0.88
  0.7   0.9658
  0.65  0.6684

我的目标是实现下面的数据集,其中包含一组新变量,使用与我的初始集不同的权重:

    A        B      A_10    A_20    A_30    A_40    A_50
    0.8     0.9     0.89    0.88    0.87    0.86    0.85
    0.99    0.88    0.891   0.902   0.913   0.924   0.935
    0.7     0.9658  0.93922 0.91264 0.88606 0.85948 0.8329
    0.65    0.6684  0.66656 0.66472 0.66288 0.66104 0.6592

我使用的代码是:

   for (i in 10:90) {
        df <- df %>% mutate(A_[i] =(A*[i]/100)+(B*((1-[i])/100))) }

我收到以下错误:

错误:意外的 '=' in:" df % mutate(A_[i] ="*

【问题讨论】:

    标签: r loops dplyr iteration


    【解决方案1】:

    主要是要动态命名dplyr,您应该使用语法%&gt;% mutate(!!paste0("BG_", i) := A + B)

    for (i in seq(10, 90, 10)) {
    
      df <- df %>% 
        mutate(!!paste0("BG_", i) := (A*i/100)+(B*((1-i)/100))) 
    }
    
    df
    #    A      B     BG_10     BG_20     BG_30     BG_40     BG_50     BG_60
    # 1 0.80 0.9000 -0.001000 -0.011000 -0.021000 -0.031000 -0.041000 -0.051000
    # 2 0.99 0.8800  0.019800  0.030800  0.041800  0.052800  0.063800  0.074800
    # 3 0.70 0.9658 -0.016922 -0.043502 -0.070082 -0.096662 -0.123242 -0.149822
    # 4 0.65 0.6684  0.004844  0.003004  0.001164 -0.000676 -0.002516 -0.004356
    #     BG_70     BG_80     BG_90
    # 1 -0.061000 -0.071000 -0.081000
    # 2  0.085800  0.096800  0.107800
    # 3 -0.176402 -0.202982 -0.229562
    # 4 -0.006196 -0.008036 -0.009876
    

    使用的数据:

    df <- read.table(text = "A    B
    0.8   0.9
    0.99  0.88
    0.7   0.9658
    0.65  0.6684", head=T)
    

    【讨论】:

    • 应该是seq(10, 90, 10)。
    • hi 和 tks 再次以这种方式实现了 byt 然后它只创建了变量 BG_90.... 请参见下面的代码 ::::for (i in seq(from=10, to=90, by=10)) { df2 % mutate(!!paste0("BG_", i) := (BG_total*i)+(onet_total*((100-1)/100))) }跨度>
    • @Suren,嗨,如果我为 (i in 10:90) 做,我会得到 85 个变量具体来说,我只得到最后一次迭代 BG_90。
    【解决方案2】:

    我们也可以将其解析为表达式

    library(tidyverse)
    library(rlang)
    s1 <- seq(10, 90, 10)
    # or could be
    #s1 <- 10:90
    expr1 <- paste(glue::glue("(A * {s1} + B * (100 - {s1}))/100"), collapse=";")
    nm1 <- paste0("A_", s1)   
    out <- df %>%
            mutate(!!! parse_exprs(expr1)) %>%
            rename_at(vars(-one_of(names(df))), ~ nm1)
    
    out
    #     A      B    A_10    A_20    A_30    A_40   A_50    A_60    A_70    A_80    A_90
    #1 0.80 0.9000 0.89000 0.88000 0.87000 0.86000 0.8500 0.84000 0.83000 0.82000 0.81000
    #2 0.99 0.8800 0.89100 0.90200 0.91300 0.92400 0.9350 0.94600 0.95700 0.96800 0.97900
    #3 0.70 0.9658 0.93922 0.91264 0.88606 0.85948 0.8329 0.80632 0.77974 0.75316 0.72658
    #4 0.65 0.6684 0.66656 0.66472 0.66288 0.66104 0.6592 0.65736 0.65552 0.65368 0.65184
    

    【讨论】:

      【解决方案3】:

      Base R 替代方式:

      df[paste0('A_', seq(10, 90, 10))] <- 
          lapply(seq(10, 90, 10), function(i) (df$A * i + df$B * (100 - i)) / 100)
      # > df
      #      A      B    A_10    A_20    A_30    A_40   A_50    A_60    A_70    A_80    A_90
      # 1 0.80 0.9000 0.89000 0.88000 0.87000 0.86000 0.8500 0.84000 0.83000 0.82000 0.81000
      # 2 0.99 0.8800 0.89100 0.90200 0.91300 0.92400 0.9350 0.94600 0.95700 0.96800 0.97900
      # 3 0.70 0.9658 0.93922 0.91264 0.88606 0.85948 0.8329 0.80632 0.77974 0.75316 0.72658
      # 4 0.65 0.6684 0.66656 0.66472 0.66288 0.66104 0.6592 0.65736 0.65552 0.65368 0.65184
      

      【讨论】:

      • @this 就像手套一样完美!非常感谢所有 R 社区
      猜你喜欢
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 2020-01-16
      • 2018-06-17
      • 2012-01-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多