2016-07-21 3 views
1

내 그룹 ("name"변수) 내에서 분위수으로 값을 잘라야합니다. 그리고 변수 "value"에 대한 4 분위수 레이블 열을 만듭니다. 그룹 크기가이므로, 다른 그룹의 범위는 입니다.도 변경됩니다. 코드 아래의이지만 전체 값에 따라 사 분위수를 자르기 만하면 같은 사 분위수범위이 모든 그룹에 적용됩니다.그룹 크기가 다른 그룹 별 분류 레이블

dt<-data.frame(name=c(rep('a',8),rep('b',4),rep('c',5)),value=c(1:8,1:4,1:5)) 
dt 
dt.2<-dt%>% group_by(name)%>% mutate(newcol= 
cut(value,breaks=quantile(value,probs=seq(0,1,0.25),na.rm=TRUE),include.lowest=TRUE)) 
dt.2 
str(dt.2) 

데이터 : 위의 코드에서

name value 
1  a  1 
2  a  2 
3  a  3 
4  a  4 
5  a  5 
6  a  6 
7  a  7 
8  a  8 
9  b  1 
10 b  2 
11 b  3 
12 b  4 
13 c  1 
14 c  2 
15 c  3 
16 c  4 
17 c  5 

출력. 업데이트 : 문제는 newcol이 factor는 아니지만 necol은 모든 다른 그룹에서 같은 사 분위 범위를가집니다. 예를 들어 이름이 b 인 경우 값은 1-4이지만 사분원 범위는 그룹에 관계없이 min (값)에서 max (값)까지 파생 된 3-5입니다.

name value newcol 
    <fctr> <int> <fctr> 
1  a  1 [1,2] 
2  a  2 [1,2] 
3  a  3 (2,3] 
4  a  4 (3,5] 
5  a  5 (3,5] 
6  a  6 (5,8] 
7  a  7 (5,8] 
8  a  8 (5,8] 
9  b  1 [1,2] 
10  b  2 [1,2] 
11  b  3 (2,3] 
12  b  4 (3,5] 
13  c  1 [1,2] 
14  c  2 [1,2] 
15  c  3 (2,3] 
16  c  4 (3,5] 
17  c  5 (3,5] 

원하는 출력

name value newcol/quartile label 

1  a  1 1 
2  a  2 1 
3  a  3 2 
4  a  4 2 
5  a  5 3 
6  a  6 3 
7  a  7 4 
8  a  8 4 
9  b  1 1 
10  b  2 2 
11  b  3 3 
12  b  4 4 
13  c  1 1 
14  c  2 2 
15  c  3 3 
16  c  4 4 
17  c  5 4 
+0

'cut'출력은'factor '즉'as.numeric (cut (...'또는'findInterval'을 사용하십시오.) – akrun

+0

@akrun Quartile을위한 숫자 레이블을 얻는 방법을 지적 해 주셔서 감사합니다 . 그러나 문제는 newcol이 모든 다른 그룹에서 동일한 4 분위수 범위를 갖는다는 것입니다. 나는 그것을 명확히하기 위해 질문을 업데이트 할 것이다. – alphabetagamma

답변

1

여기 당신이 그것을 할 수있는 방법은 다음,의 분할 신청 - 통합 프레임 워크를.

dt<-data.frame(name=c(rep('a',8),rep('b',4),rep('c',5)),value=c(1:8,1:4,1:5)) 

split_dt <- lapply(split(dt, dt$name), 
        transform, 
        quantlabel = as.numeric(
cut(value, breaks = quantile(value, probs = seq(0,1,.25)), include.lowest = T))) 

dt <- unsplit(split_dt, dt$name) 

    name value quantlabel 
1  a  1   1 
2  a  2   1 
3  a  3   2 
4  a  4   2 
5  a  5   3 
6  a  6   3 
7  a  7   4 
8  a  8   4 
9  b  1   1 
10 b  2   2 
11 b  3   3 
12 b  4   4 
13 c  1   1 
14 c  2   1 
15 c  3   2 
16 c  4   3 
17 c  5   4 

편집 :

library(data.table) 
dt<-data.frame(name=c(rep('a',8),rep('b',4),rep('c',5)),value=c(1:8,1:4,1:5)) 
dt.t <- as.data.table(dt) 
dt.t[,quantlabels := as.numeric(cut(value, breaks = quantile(value, probs = seq(0,1,.25)), include.lowest = T)), name] 

    name value quantlabels 
1: a  1   1 
2: a  2   1 
3: a  3   2 
4: a  4   2 
5: a  5   3 
6: a  6   3 
7: a  7   4 
8: a  8   4 
9: b  1   1 
10: b  2   2 
11: b  3   3 
12: b  4   4 
13: c  1   1 
14: c  2   1 
15: c  3   2 
16: c  4   3 
17: c  5   4 

편집 : this post을 따르는 data.table 방법

거기, 성능이 문제가되는 경우 우리는 data.table 패키지를 사용할 수 있으며, dplyr 방법이

우리는 akrun의 조언 @ 따라 (우리는 다른 솔루션에 대해 무슨 짓을했는지입니다) as.numeric를 사용할 수 있습니다 대신 라벨 자체를 원한다면

dt %>% 
    group_by(name) %>% 
    mutate(quantlabel = 
       as.numeric(
        cut(value, 
         breaks = quantile(value, probs = seq(0,1,.25)), 
         include.lowest = T))) 

주, as.character를 사용하는 것이 :

dt %>% 
    group_by(name) %>% 
    mutate(quantlabel = as.character(cut(value, breaks = quantile(value, probs = seq(0,1,.25)), include.lowest = T))) 

Source: local data frame [17 x 3] 
Groups: name [3] 

    name value quantlabel 
    <fctr> <int>  <chr> 
1  a  1 [1,2.75] 
2  a  2 [1,2.75] 
3  a  3 (2.75,4.5] 
4  a  4 (2.75,4.5] 
5  a  5 (4.5,6.25] 
6  a  6 (4.5,6.25] 
7  a  7 (6.25,8] 
8  a  8 (6.25,8] 
9  b  1 [1,1.75] 
10  b  2 (1.75,2.5] 
11  b  3 (2.5,3.25] 
12  b  4 (3.25,4] 
13  c  1  [1,2] 
14  c  2  [1,2] 
15  c  3  (2,3] 
16  c  4  (3,4] 
17  c  5  (4,5] 
+0

감사합니다! 귀하의 코드는 내 코드와 매우 유사하게 보이며 작동합니다. 하지만 왜 여기 group_by가 제 코드를 자르지 않는지 궁금합니다. – alphabetagamma

+0

@Phdaml 나는 'dplyr' 전문가가 아니기 때문에 왜 작동하지 않을지 잘 모르겠습니다. – bouncyball

+0

나는 왜 내 그룹이 작동하지 않는지를 알아 냈다. 필자는 어떻게 든 dplyr 패키지를 연결 해제했지만 코드를 실행 한 후에 오류가 표시되지 않습니다. – alphabetagamma