【问题标题】:Multiple Variable Values to Function and Cbind Results函数和 Cbind 结果的多个变量值
【发布时间】:2018-05-09 14:57:42
【问题描述】:

这是此问题的延续: For-Loop By Columns with existing For-loop by Rows

我有一个使用 3 个变量的数据集: adstock_ratediminishing_ratelag_number . 这些当前设置为每个仅 1 个数字。

目前我正在使用以下数字:

adstock_rate<-0.5
lag_number<-1
diminishing_rate<-0.6

最终输出是使用以下函数将新列附加到现有数据集的数据集。

foo1 <- function(dot, lag_val = 1) {
     tmp <- dot
     for(i in (1 + lag_val): length(tmp)) {
           tmp[i] <- tmp[i] + adstock_rate * diminishing_rate * tmp[i - lag_val]
     }
     return(tmp)
   }


advertising_dataset %>%
       group_by(Region) %>%
       mutate_all(funs(adstocked = foo1(., lag_val = lag_number)))

这是我想要做的:

我想将此函数应用于这些变量的不同值。以下是这些变量的组合:

adstock_rate = c(0.50, 0.60, 0.70)
lag_number = c(0,1)
diminishing_rate = c(0.50, 0.60)

combos<-expand.grid(adstock_rate,lag_number,diminishing_rate)
colnames(combos)[1]<-"AdStock_Rate"
colnames(combos)[2]<-"Lag_Number"
colnames(combos)[3]<-"Diminish_Rate"


head(combos)

   AdStock_Rate Lag_Number Diminish_Rate
1           0.5          0           0.5
2           0.6          0           0.5
3           0.7          0           0.5
4           0.5          1           0.5
5           0.6          1           0.5
6           0.7          1           0.5
7           0.5          0           0.6
8           0.6          0           0.6
9           0.7          0           0.6
10          0.5          1           0.6

我认为您必须创建一个 for 循环或使用 apply 函数来查看组合数据集中的行列表。

这是我的尝试:

for(j in combos){
foo1 <- function(dot, lag_val = 1) {
     tmp <- dot
     for(i in (1 + lag_val): length(tmp)) {
           tmp[i] <- tmp[i] + combos[j,1] * combos[j,3] * tmp[i - lag_val]
     }
     return(tmp)
   }


advertising_dataset %>%
       group_by(Region) %>%
       mutate_all(funs(adstocked = foo1(., lag_val = combos[j,2])))

##cbind to previous output
}

我还需要列名具有数字值,例如 adstock_0.5_1_0.6,其中 0.5 = 广告库存率,1 = 滞后数,递减 = 0.6。

希望这是有道理的。

如果您需要我提供更多信息,请告诉我。

谢谢!

【问题讨论】:

    标签: r for-loop cbind


    【解决方案1】:

    补充@akrun 的答案。如果我们想以列的形式显示它,这就是你的做法。 @akrun 如果您认为有更好的方法,请告诉我:

    test<-out %>%
      gather(var, value, -(id:Region)) %>%
      unite(var, var, id, sep="_") %>%
      spread(var, value)
    colnames(test)
    colnames(test) = gsub("_adstock_", "+", colnames(test))
    colnames(test) = gsub("^(?!.*adstocked)([^+]*)\\+.*","\\1", colnames(test), perl=TRUE)
    
    non_dupe<-test[!duplicated(as.list(test))]
    

    【讨论】:

      【解决方案2】:

      当我们遍历“combos”的行时,创建一个list,它与“combos”的行数相同,length 用于存储来自for 循环的输出

      lst <- vector("list", nrow(combos)) # initialize a list to store output
      

      在 'foo1' 中添加更多参数以获得更大的灵活性

      foo1 <- function(dot, lag_val = 1, combos, ind) {
           tmp <- dot
           for(i in (1 + lag_val): length(tmp)) {
                 tmp[i] <- tmp[i] + combos[ind,1] * combos[ind,3] * tmp[i - lag_val]
           }
           return(tmp)
         }
      

      然后循环遍历'combos'的行

      for(j in seq_len(nrow(combos))){
      
      # assign the group by recursive output to each `list` element        
      
      
      lst[[j]] <- advertising_dataset %>%
                   group_by(Region) %>%
                   mutate_all(funs(adstocked =
                     foo1(., lag_val = combos[j,2], combos, ind = j)))
      
      }
      lst
      

      尚不清楚我们是否需要将list 名称设为“adstock_Rate_Number_Drate”。如果是这样的话,

      names(lst) <- paste0("adstock_", do.call(paste, c(combos, sep="_")))
      

      data.framelist 转换为具有“id”列以指示组合的单个data.frame

      out <- bind_rows(lst, .id = 'id')
      head(out, 3)
      # A tibble: 3 x 6
      # Groups:   Region [1]
      #  id        Region advertising advertising2 advertising_adst… advertising2_ads…
      #  <chr>      <dbl>       <dbl>        <dbl>             <dbl>             <dbl>
      #1 adstock_…    500        118.         43.9              147.              54.9
      #2 adstock_…    500        120.        231.               150.             289. 
      #3 adstock_…    500        126.         76.8              157.              96.0
      

      【讨论】:

      • 这太棒了!谢谢你。有没有办法把它放在一个数据框中而不是列表中? adstock_0.5_0_0.7 将附加到应用于它的列名称上,因此没有重复的列标题,例如:“advertising_adstock_0.5_0_0.7”、“advertising2_adstock_0.5_0_0.7”等。这样我们就知道哪个组合应用于哪一列?
      • @nak5120 是的,我们可以做到bind_rows(lst, .id = 'grp')
      • 最好将列作为我提到的单独列,而不是更改列名,这也会在加入单个数据集时产生问题
      • 我将在短期内使用它,但我认为从长远来看它会很艰难。虽然会接受答案。谢谢!
      • 这是有道理的。谢谢。
      猜你喜欢
      • 2018-09-04
      • 2016-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-19
      • 1970-01-01
      相关资源
      最近更新 更多