2016-08-28 202 views
1
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 

我有這個示例數據框架。我想使用cum_success_rate變量創建變量success_rate_trend。面臨的挑戰是我希望它每activity_id計算除了每個唯一的people_id的第一個活動,即我想捕獲唯一people_id的成功趨勢。我正在使用以下代碼:For循環R需要永遠運行

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

使用矢量:

success_rate_trend <- diff(succ_rate_df$cum_success_rate) 
success_rate_trend[diff(as.integer(succ_rate_df$people_id)) != 0] <- NA_real_ 

注:

  1. people_id是一個因素變量(fctr)。要使用diff(),我們必須使用as.integer()unclass()來刪除因子類別。
  2. 您沒有普通的數據框,但是dplyrtbl_df。類似索引的矩陣不起作用。使用succ_rate_df$people_idsucc_rate_df[["people_id"]]而不是succ_rate_df[, 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 

由李宋哲元的答案是整潔。

0

我打算根據此數據的數據幀版本提供答案。您應該學習使用dput的輸出進行發佈,以便可以將具有特殊屬性的對象(例如上面打印的tibble)複製到其他用戶控制檯中,而不會丟失任何屬性。我也將命名我的數據幀dat。當您希望它們與輸入向量具有相同的長度時,ave函數適用於計算數值向量,但希望將這些計算限制爲對向量進行分組。我只使用了一個分組因子,儘管你對英語問題的描述表明你想要兩個分組因子。有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 
+0

感謝您的反饋。 – Abhi