2016-08-28 2 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 

이 샘플 데이터 프레임을 가지고 있습니다. 변수 success_rate_trend을 만들고 cum_success_rate 변수를 사용하고 싶습니다. 문제는 모든 고유 한 people_id에 대한 첫 번째 활동을 제외하고 모든 activity_id에 대해 계산하기를 원합니다. 즉 고유 한 성공 추세를 포착하고자합니다. people_id. 아래 코드를 사용하고 있습니다.For loop in 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. 일반 데이터 프레임이 없지만 tbl_dfdplyr입니다. 인덱스와 같은 매트릭스가 작동하지 않습니다. succ_rate_df[, 1] 대신 succ_rate_df$people_id 또는 succ_rate_df[["people_id"]]을 사용하십시오.
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 

Zheyuan는 리튬에 의한 응답은 깔끔.

0

이 데이터의 데이터 프레임 버전을 기반으로 답변을 제공 할 예정입니다. dput의 출력으로 게시하는 법을 배워야합니다. 위 인쇄물과 같은 특수한 속성을 가진 객체를 속성 손실없이 다른 사용자 콘솔에 복사 할 수 있습니다. 데이터 프레임 이름을 dat으로 지정하겠습니다. ave 함수는 숫자 벡터를 입력 벡터와 길이를 같게하고 해당 벡터를 그룹화하도록 제한 할 때 벡터를 계산하는 데 적합합니다. 문제의 영어 설명을 통해 두 가지를 원하지만 하나의 그룹화 요소 만 사용했습니다. ave으로 그룹화하는 두 가지 요소가있는 SO 작업 예제가 있습니다.

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