2016-07-19 1 views
1

저는 R을 처음 접하고 기본적인 것을 배웁니다. 나는 data_frame을 R에서 column_value, user_id, mth_id, col_val1, col_val100까지 가지고있다.R의 컬럼 값을 기반으로 한 데이터 프레임의 행간 차이 결과 계산 및 저장

df <- data.frame('controller_id' = c('X','X','X','X','X','X','Y','Y','Y','Y','Y','Y','Z','Z'), 
'user_id'=c('A','B','C','A','B','C','P','Q','R','P','Q','R',NA,NA), 
'mth_id'=c('1393','1393','1393','1398','1398','1398','1393','1393','1393','1398','1398','1398','1393','1398'), 
'col_val1' = c(5,4,6,3,1,10,12,15,18,13,19,1,5,2), 
'col_val2'=c(8,12,9,2,12,5,7,9,11,4,0,7,10,5)) 

> df 
    controller_id user_id mth_id col_val1 col_val2 
1    X  A 1393  5  8 
2    X  B 1393  4  12 
3    X  C 1393  6  9 
4    X  A 1398  3  2 
5    X  B 1398  1  12 
6    X  C 1398  10  5 
7    Y  P 1393  12  7 
8    Y  Q 1393  15  9 
9    Y  R 1393  18  11 
10    Y  P 1398  13  4 
11    Y  Q 1398  19  0 
12    Y  R 1398  1  7 
13    Z <NA> 1393  5  10 
14    Z <NA> 1398  2  5 

는 내가 원하는 특정 USER_ID, mth_id 및 표시합니다 mth_id이 증가로 감소들만 col_values에 따라 각 controller_id에 대한 col_values의 차이를 계산하는 것이다.

예 : controller_id = X의 경우 두 개의 서로 다른 mth_ids에 대해 3 개의 user_id가 A, B, C로 있습니다. 코드 3 users_id에 대한 mth_id 1398 및 1393에 대한 col_val1 사이의 차이를 계산해야하며, 그 차이가 < 0 다음의 경우 나는

Col_val1 for controller_id 'X', user_id 'A' has decreased from 5 to 3 

같은 출력을 원하는에 대한 만약 다음이를 계산한다 관련된 USER_ID가없는 controller_id 제공 controller_id 자체 사이의 열 값 차이.

이상적으로이 출력을 나중에 사용할 수 있도록 목록/데이터 프레임에 저장하고 싶습니다. 또한 코드는 대략 실행해야합니다. 데이터 프레임에 900 개의 열이 있습니다.

도움을 주시면 감사하겠습니다.

+0

@akrun을 당신이 어떤을해야합니까 제안? –

답변

0

실행 그룹 합계를 사용하여 기본 R 솔루션을 고려하십시오.

rowdiff <- function(col) { 
      sapply(1:nrow(df), 
       function(i){ 
       # CONDITIONAL TO RETURN NA FOR FIRST VAL IN EACH USER ID 
       ifelse(sum(df[1:i, c("user_id")] == df$user_id[i]) == 1, NA, 
        # DIFFERENCE OF CURRENT LOOP COL VALUE - LAST COL VALUE OF USER ID GROUP 
        df[[col]][i] - 
        sum((df[1:i-1, c("user_id")] == df$user_id[i]) 
        * df[1:i-1,][[col]])) 
       }) 
      } 


finaldf <- cbind(df, data.frame(sapply(names(df[c(3:ncol(df))]), rowdiff))) 

# user_id mth_id col_val1 col_val2 col_val3 col_val1 col_val2 col_val3 
# 1  A 1398  4  2  12  NA  NA  NA 
# 2  B 1398  3  3  30  NA  NA  NA 
# 3  C 1398  1  1  14  NA  NA  NA 
# 4  A 1393  5  7  7  1  5  -5 
# 5  B 1393  2  6  18  -1  3  -12 
# 6  C 1393  7  0  9  6  -1  -5 
# 7  D 1398  4  5  12  NA  NA  NA 
# 8  D 1393  0  3  24  -4  -2  12 

을 그리고 당신은 기입 문이 필요합니다 : : 그리고 모든 컬럼에 걸쳐 반복, 열 이름에 통과하는 sapply()를 사용

statements <- function(col) { 
    sapply(1:nrow(df), 
     function(i){ 

      delta <- df[[col]][i]- 
         sum((df[1:i-1, c("controller_id")] == df$controller_id[i]) 
         *(df[1:i-1, c("user_id")] == df$user_id[i]) 
         * df[1:i-1,][[col]]) 

      changeword <- ifelse(delta < 0, "decreased", 
           ifelse(delta > 0, "increased", "not changed")) 

      ifelse(sum(df[1:i, c("user_id")] == df$user_id[i]) == 1, NA, 
        paste0(col, " for controller_id '", df$controller_id[i], "', user_id '", 
         df$user_id[i], "' has ", changeword, " from ", 
         sum((df[1:i-1, c("controller_id")] == df$controller_id[i]) 
          * (df[1:i-1, c("user_id")] == df$user_id[i]) 
          * df[1:i-1,][[col]]), " to ", 
         df[[col]][i]) 

      ) 
     }) 
} 
finaldf <- cbind(df, data.frame(sapply(names(df[c(4:ncol(df))]), statements))) 

출력

                col_val1 
1                  <NA> 
2                  <NA> 
3                  <NA> 
4 col_val1 for controller_id 'X', user_id 'A' has decreased from 5 to 3 
5 col_val1 for controller_id 'X', user_id 'B' has decreased from 4 to 1 
6 col_val1 for controller_id 'X', user_id 'C' has increased from 6 to 10 
7                  <NA> 
8                  <NA> 
9                  <NA> 
10 col_val1 for controller_id 'Y', user_id 'P' has increased from 12 to 13 
11 col_val1 for controller_id 'Y', user_id 'Q' has increased from 15 to 19 
12 col_val1 for controller_id 'Y', user_id 'R' has decreased from 18 to 1 
13                 <NA> 
14                 <NA> 
                    col_val2 
1                  <NA> 
2                  <NA> 
3                  <NA> 
4  col_val2 for controller_id 'X', user_id 'A' has decreased from 8 to 2 
5 col_val2 for controller_id 'X', user_id 'B' has not changed from 12 to 12 
6  col_val2 for controller_id 'X', user_id 'C' has decreased from 9 to 5 
7                  <NA> 
8                  <NA> 
9                  <NA> 
10  col_val2 for controller_id 'Y', user_id 'P' has decreased from 7 to 4 
11  col_val2 for controller_id 'Y', user_id 'Q' has decreased from 9 to 0 
12 col_val2 for controller_id 'Y', user_id 'R' has decreased from 11 to 7 
13                  <NA> 
14                  <NA> 
+0

답장을 보내 주셔서 감사합니다. 도움이되었다. 그러나, 내 문제 성명서 약간의 수정있어. 나는 선택할 수있는 계층 적 레벨이 하나 더있다. 지금이 문제를 해결할 수있는 변경 사항을 제안 할 수 있습니까? –

+0

Hey @Parfait 값에 변화가 없다면 어떨까요? 델타가 증가하거나 감소했기 때문에 조건에 변화가 없으면 값을 변경하지 않고 인쇄하고 싶습니다. 그게 어떻게 할 수있는 모든 제안. –

+0

계층 적 'controller_id'및 * 증가하지 않는 시나리오를 모두 처리하는 업데이트를 참조하십시오. 'mth_id'에 의해 데이터 프레임을 주문하라. 그래서 1393은 1398s 이전에 올 것이다. – Parfait

관련 문제