【问题标题】:Looping with dplyr on each row of dataframe在每一行数据帧上使用 dplyr 循环
【发布时间】:2017-11-30 07:59:05
【问题描述】:

我有一个数据框

df <- data.frame(var1=c(10,20,30,40,50), var2=c(rep(0.3,5)), BYGROUP_OBSNUM=c(0:4))

var1 var2 BYGROUP_OBSNUM
10   0.3          0
20   0.3          1
30   0.3          2
40   0.3          3
50   0.3          4

我需要使用 dplyr 对每一行执行计算,因为我的真实数据框非常庞大,并且 dplyr 非常高效。

我想要什么:

var1    var2    BYGROUP_OBSNUM  VAR1_NEW
10       0.3       0              10
20       0.3       1              23
30       0.3       2              36.9
40       0.3       3              51.07
50       0.3       4              65.321

这是如何实现的:

var1    var2    BYGROUP_OBSNUM  VAR1_NEW    
10       0.3         0           10
20       0.3         1           20+10*0.3
30       0.3         2           30+20*0.3+10*0.3^2
40       0.3         3           40+30*0.3+20*0.3^2+10*0.3^3
50       0.3         4           50+40*0.3+30*0.3^2+20*0.3^3+10*0.3^4

因此对于每一行,公式为:

 var1[i]+lag(var1,1)*var2^1+lag(var1,2)*var2^2 +.... 

直到 lag(var1) 到达 BYGROUP_OBSNUM 为 0 的行

到目前为止我已经取得的成就:

df1<-df %>%
   mutate(var3=ifelse ((!(var2==0) | (!(BYGROUP_OBSNUM==0))),  var2, 0)) %>%
    rowwise()%>%
     ungroup() %>%
      mutate(var1_new=var1+lag(var1,1)*var2)

我需要更改最后一行,以便公式将每行的滞后从 lag(var1,1) 变为 lag(var1,BYGROUP_OBSNUM),并且 var2 的幂也从 1 增加到 BYGROUP_OBSNUM。我该怎么做?

【问题讨论】:

  • 我猜ungroup() 取消了rowwise()。所以这没有做任何事情。
  • 是的 rowwise 没用..df1% mutate(var3=ifelse ((!(var2==0) | (!(BYGROUP_OBSNUM==0))), var2, 0 )) %>% 变异(var1_new=var1+lag(var1,1)*var2)
  • 不确定你的分组是什么,但在基础 R 中你可以做类似with(df, sapply(seq_along(var1), function(i) sum(var1[seq_len(i-1)]*0.3^(rev(seq_len(i-1))))) + var1)
  • 这有帮助,但仅适用于小型数据集。即使是 1 百万行的数据集也需要很长时间。有一些分类变量用于分组,在 BYGROUP_OBSNUM 列的基础上进行分组。

标签: r loops dataframe dplyr


【解决方案1】:

这是一个自定义函数,可与 dplyr 一起使用以产生您所追求的结果。它也适用于group_by 函数。

my.func <- function(x){
             mapply(function(v1,v2,n) {
               if(n == 1) {
                 as.numeric(v1[n])
               } else {
                 sum(v1, x[rev(seq(1:(n-1))),1] * v2 ^ seq(1:(n-1)))
               }
             }, x[,"var1"], x[,"var2"], seq(1:nrow(x)))
           }


df <- df %>% 
      # group_by(COLUMNS, TO, GROUP, BY) %>% 
      do(data.frame(., my.func(.))) %>%
      select(var1, var2, BYGROUP_OBSNUM, VAR1_NEW = my.func...)

【讨论】:

    【解决方案2】:

    做出了最终的解决方案——

    df<-data.frame(var1=c(1:10),var2=c(rep(c(0,0.1),each=5)),BYG‌​ROUP_OBSNUM=c(0:4)) 
    
    my.func <- function(x){mapply(function(v1,v2,v3,n) {
                  if(v2==0 | v3==0){ as.numeric(v1) } 
                  else { 
                  sum(v1, x[rev(seq(1:(n-1))),1][1:v3] * v2 ^ seq(1:(n-1))[1:v3]) } },
                 x[,"var1"], x[,"var2"], x[,"BYGROUP_OBSNUM"],seq(1:nrow(x))) 
                }
    
    df1 <- df %>%   
             do(data.frame(., my.func(.))) %>% 
              mutate(VAR1_NEW = my.func...)%>% 
               select(-my.func...)
    

    在 1.42 分钟内完成了 10 万行!这个功能帮了大忙!谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      相关资源
      最近更新 更多