对于R中的循环需要永远运行

时间:2016-08-28 22:05:01

标签: r

    people_id  activity_id success totl_act success_rate cum_success cum_act cum_success_rate success_rate_trend
       (fctr)       (fctr)   (int)    (int)        (dbl)       (int)   (int)            (dbl)              (dbl)
1     ppl_100 act2_1734928       0        1            0           0       1                0                 NA
2     ppl_100 act2_2434093       0        1            0           0       2                0                  0
3     ppl_100 act2_3404049       0        1            0           0       3                0                  0
4     ppl_100 act2_3651215       0        1            0           0       4                0                  0
5     ppl_100 act2_4109017       0        1            0           0       5                0                  0
6     ppl_100  act2_898576       0        1            0           0       6                0                  0
7  ppl_100002 act2_1233489       1        1            1           1       1                1                  1
8  ppl_100002 act2_1623405       1        1            1           2       2                1                  0
9  ppl_100003 act2_1111598       1        1            1           1       1                1                  0
10 ppl_100003 act2_1177453       1        1            1           2       2                1                  0

我是这个样本数据框。我想使用success_rate_trend变量创建变量cum_success_rate。面临的挑战是,除了每个唯一activity_id的第一个活动之外,我希望它为每个people_id计算,即我想捕获唯一people_id的成功趋势。我使用以下代码:

success_rate_trend<-vector(mode="numeric", length=nrow(succ_rate_df)-1)
for(i in 2:nrow(succ_rate_df)){
     if(succ_rate_df[i,1]!=succ_rate_df[i-1,1]){
         success_rate_trend[i] = NA
       }
        else {
          success_rate_trend[i]<-succ_rate_df[i,8]-succ_rate_df[i-1,8]
    }}

运行需要永远。我在succ_rate_df数据框中接近了数百万行。任何人都可以建议如何简化代码并缩短运行时间。

3 个答案:

答案 0 :(得分:3)

使用矢量化:

people_id

注意:

  1. (fctr)是因子变量diff()。要使用as.integer(),我们必须使用unclass()tbl_df删除因子类。
  2. 您没有普通的数据框,而是来自dplyr的{​​{1}}。像索引这样的矩阵不起作用。使用succ_rate_df$people_idsucc_rate_df[["people_id"]]代替succ_rate_df[, 1]

答案 1 :(得分:1)

您应该能够使用矢量化方法进行此计算。这将快几个数量级。

n = nrow(succ_rate_df)
success_rate = succ_rate_df[2:n,1] == succ_rate_df[1:(n-1),1]
is_true = which(success_rate)

success_rate[is_true] = succ_rate_df[is_true+1,8]-succ_rate_df[is_true,8]
success_rate[!success_rate] = NA

李哲元的回答是整洁的。

答案 2 :(得分:0)

我将根据此数据的数据框版本提供答案。您应该学会使用dput的输出进行发布,以便具有特殊属性的对象(如上面打印的tibble)可以复制到其他用户控制台而不会丢失属性。我还要命名我的数据帧datave函数适用于计算数值向量时,如果希望它们与输入向量的长度相同,但希望这些计算仅限于对向量进行分组。我只使用了一个分组因子,尽管你对这个问题的英语描述表明你想要两个。有一些SO工作示例有两个因素可以用ave进行分组。

 success_rate_trend <- with( dat, 
                    ave( cum_success_rate, people_id, FUN= function(x) c(NA, diff(x) ) ) )

 success_rate_trend
 [1] NA  0  0  0  0  0 NA  0 NA  0
 # not a very interesting result