각 그룹에 대해 데이터프레임의 모든 변수에 대한 평균을 요약합니다(ddply?나뉘다?)

StackOverflow https://stackoverflow.com/questions/1407449

  •  05-07-2019
  •  | 
  •  

문제

일주일 전에는 이 작업을 수동으로 수행했을 것입니다.그룹별로 데이터 프레임을 새 데이터 프레임으로 하위 집합합니다.각 데이터프레임에 대해 각 변수에 대한 평균을 계산한 다음 rbind를 수행합니다.매우 투박하다 ...

이제 나는 대해 배웠습니다. split 그리고 plyr, 이러한 도구를 사용하는 더 쉬운 방법이 있을 것 같습니다.내가 틀렸다는 것을 증명하지 마십시오.

test_data <- data.frame(cbind(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T)))

test_data$var1 <- as.numeric(as.character(test_data$var1))
test_data$var2 <- as.numeric(as.character(test_data$var2))
test_data$var3 <- as.numeric(as.character(test_data$var3))
test_data$var4 <- as.numeric(as.character(test_data$var4))

난 둘 다 갖고 놀고 있어 ddply 하지만 나는 내가 원하는 것을 생산할 수 없습니다.각 그룹마다 이런 테이블이 있어요

group a |2007|2009|
________|____|____|
var1    | xx | xx |
var2    | xx | xx |
etc.    | etc| ect|

아마도 d_ply 그리고 일부 odfweave 출력이 작동합니다.의견을 보내주시면 매우 감사하겠습니다.

추신.data.frame이 rnorm을 내 data.frame의 요소로 변환하는 것을 확인했습니다.이를 방지하려면 어떻게 해야 합니까? I(rnorm(100)이 작동하지 않으므로 위에서 수행한 대로 숫자로 변환해야 합니다.

도움이 되었습니까?

해결책

결과에 원하는 형식이 주어지면 재구성 패키지는 PlyR보다 효율적입니다.

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

library(reshape)
Molten <- melt(test_data, id.vars = c("group", "year"))
cast(group + variable ~ year, data = Molten, fun = mean)

결과는 다음과 같습니다

   group variable         2007         2009
1      a     var0  0.003767891  0.340989068
2      a     var1  2.009026385  1.162786943
3      a     var2  1.861061882  2.676524736
4      a     var3  2.998011426  3.311250399
5      a     var4  3.979255971  4.165715967
6      b     var0 -0.112883844 -0.179762343
7      b     var1  1.342447279  1.199554144
8      b     var2  2.486088196  1.767431740
9      b     var3  3.261451449  2.934903824
10     b     var4  3.489147597  3.076779626
11     c     var0  0.493591055 -0.113469315
12     c     var1  0.157424796 -0.186590644
13     c     var2  2.366594176  2.458204041
14     c     var3  3.485808031  2.817153628
15     c     var4  3.681576886  3.057915666
16     d     var0  0.360188789  1.205875725
17     d     var1  1.271541181  0.898973536
18     d     var2  1.824468264  1.944708165
19     d     var3  2.323315162  3.550719308
20     d     var4  3.852223640  4.647498956
21     e     var0 -0.556751465  0.273865769
22     e     var1  1.173899189  0.719520372
23     e     var2  1.935402724  2.046313047
24     e     var3  3.318669590  2.871462470
25     e     var4  4.374478734  4.522511874
26     f     var0 -0.258956555 -0.007729091
27     f     var1  1.424479454  1.175242755
28     f     var2  1.797948551  2.411030282
29     f     var3  3.083169793  3.324584667
30     f     var4  4.160641429  3.546527820
31     g     var0  0.189038036 -0.683028110
32     g     var1  0.429915866  0.827761101
33     g     var2  1.839982321  1.513104866
34     g     var3  3.106414330  2.755975622
35     g     var4  4.599340239  3.691478466
36     h     var0  0.015557352 -0.707257185
37     h     var1  0.933199148  1.037655156
38     h     var2  1.927442457  2.521369108
39     h     var3  3.246734239  3.703213646
40     h     var4  4.242387776  4.407960355
41     i     var0  0.885226638 -0.288221276
42     i     var1  1.216012653  1.502514588
43     i     var2  2.302815441  1.905731471
44     i     var3  2.026631277  2.836508446
45     i     var4  4.800676814  4.772964668
46     j     var0 -0.435661855  0.192703997
47     j     var1  0.836814185  0.394505861
48     j     var2  1.663523873  2.377640369
49     j     var3  3.489536343  3.457597835
50     j     var4  4.146020948  4.281599816

다른 팁

당신은 이것을 할 수 있습니다 by().먼저 일부 데이터를 설정하십시오.

R> set.seed(42)
R> testdf <- data.frame(var1=rnorm(100), var2=rnorm(100,2), var3=rnorm(100,3),  
                        group=as.factor(sample(letters[1:10],100,replace=T)),  
                        year=as.factor(sample(c(2007,2009),100,replace=T)))
R> summary(testdf)
      var1              var2              var3          group      year   
 Min.   :-2.9931   Min.   :-0.0247   Min.   :0.30   e      :15   2007:50  
 1st Qu.:-0.6167   1st Qu.: 1.4085   1st Qu.:2.29   c      :14   2009:50  
 Median : 0.0898   Median : 1.9307   Median :2.98   f      :12            
 Mean   : 0.0325   Mean   : 1.9125   Mean   :2.99   h      :12            
 3rd Qu.: 0.6616   3rd Qu.: 2.4618   3rd Qu.:3.65   d      :11            
 Max.   : 2.2866   Max.   : 4.7019   Max.   :5.46   b      :10            
                                                    (Other):26  

사용 by():

R> by(testdf[,1:3], testdf$year, mean)
testdf$year: 2007
   var1    var2    var3 
0.04681 1.77638 3.00122 
--------------------------------------------------------------------- 
testdf$year: 2009
   var1    var2    var3 
0.01822 2.04865 2.97805 
R> by(testdf[,1:3], list(testdf$group, testdf$year), mean)  
## longer answer by group and year suppressed

여전히 테이블에 맞게 형식을 다시 지정해야 하지만 답변의 요지를 한 줄로 제공합니다.

편집하다: 다음을 통해 추가 처리가 가능합니다.

R> foo <- by(testdf[,1:3], list(testdf$group, testdf$year), mean)  
R> do.call(rbind, foo)
          var1   var2  var3
 [1,]  0.62352 0.2549 3.157
 [2,]  0.08867 1.8313 3.607
 [3,] -0.69093 2.5431 3.094
 [4,]  0.02792 2.8068 3.181
 [5,] -0.26423 1.3269 2.781
 [6,]  0.07119 1.9453 3.284
 [7,] -0.10438 2.1181 3.783
 [8,]  0.21147 1.6345 2.470
 [9,]  1.17986 1.6518 2.362
[10,] -0.42708 1.5683 3.144
[11,] -0.82681 1.9528 2.740
[12,] -0.27191 1.8333 3.090
[13,]  0.15854 2.2830 2.949
[14,]  0.16438 2.2455 3.100
[15,]  0.07489 2.1798 2.451
[16,] -0.03479 1.6800 3.099
[17,]  0.48082 1.8883 2.569
[18,]  0.32381 2.4015 3.332
[19,] -0.47319 1.5016 2.903
[20,]  0.11743 2.2645 3.452
R> do.call(rbind, dimnames(foo))
     [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10] 
[1,] "a"    "b"    "c"    "d"    "e"    "f"    "g"    "h"    "i"    "j"   
[2,] "2007" "2009" "2007" "2009" "2007" "2009" "2007" "2009" "2007" "2009"

당신은 dimnames 좀 더:

R> expand.grid(dimnames(foo))
   Var1 Var2
1     a 2007
2     b 2007
3     c 2007
4     d 2007
5     e 2007
6     f 2007
7     g 2007
8     h 2007
9     i 2007
10    j 2007
11    a 2009
12    b 2009
13    c 2009
14    d 2009
15    e 2009
16    f 2009
17    g 2009
18    h 2009
19    i 2009
20    j 2009
R> 

편집하다: 이를 통해 우리는 data.frame 기본 R만 사용하여 외부 패키지에 의존하지 않고 결과를 얻으려면 다음을 수행하십시오.

R> data.frame(cbind(expand.grid(dimnames(foo)), do.call(rbind, foo)))
   Var1 Var2     var1   var2  var3
1     a 2007  0.62352 0.2549 3.157
2     b 2007  0.08867 1.8313 3.607
3     c 2007 -0.69093 2.5431 3.094
4     d 2007  0.02792 2.8068 3.181
5     e 2007 -0.26423 1.3269 2.781
6     f 2007  0.07119 1.9453 3.284
7     g 2007 -0.10438 2.1181 3.783
8     h 2007  0.21147 1.6345 2.470
9     i 2007  1.17986 1.6518 2.362
10    j 2007 -0.42708 1.5683 3.144
11    a 2009 -0.82681 1.9528 2.740
12    b 2009 -0.27191 1.8333 3.090
13    c 2009  0.15854 2.2830 2.949
14    d 2009  0.16438 2.2455 3.100
15    e 2009  0.07489 2.1798 2.451
16    f 2009 -0.03479 1.6800 3.099
17    g 2009  0.48082 1.8883 2.569
18    h 2009  0.32381 2.4015 3.332
19    i 2009 -0.47319 1.5016 2.903
20    j 2009  0.11743 2.2645 3.452
R> 

편집하다: 나는 다음을 썼고 Thierry가 이미 거의 같은 대답을 작성했다는 것을 깨달았습니다. 나는 어떻게 든 그의 대답을 간과했다. 이 답변이 마음에 들면 대신 투표하십시오. 시간을 입력 한 이후로 게시하고 게시하고 있습니다.


이런 종류의 물건은 내가 원하는 것보다 내 시간을 더 많이 소비합니다! 다음은 다음을 사용하는 솔루션입니다 패키지를 재구성하십시오 Hadley Wickham에 의해. 이 예제는 그렇지 않습니다 바로 그거죠 결과는 각 그룹의 테이블이 아닌 하나의 큰 테이블에 있기 때문에 요청한 것.

요인으로 숫자 값이 나타나는 문제는 CBIND를 사용하고 있었고 모든 것이 유형 문자의 매트릭스로 튀어 나왔기 때문입니다. 멋진 점은 data.frame과 함께 cbind가 필요하지 않다는 것입니다.

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

library(reshape)
molten_data <- melt(test_data, id=c("group", "year")))
cast(molten_data, group + variable ~ year, mean)

그리고 이것은 다음과 같은 결과를 초래합니다.

    group variable        2007         2009
1      a     var0 -0.92040686 -0.154746420
2      a     var1  1.06603832  0.559765035
3      a     var2  2.34476321  2.206521587
4      a     var3  3.01652065  3.256580166
5      a     var4  3.75256699  3.907777127
6      b     var0 -0.53207427 -0.149144766
7      b     var1  0.75677714  0.879387608
8      b     var2  2.41739521  1.224854891
9      b     var3  2.63877431  2.436837719
10     b     var4  3.69640598  4.439047363
...

나는 a 최근 블로그 게시물 비슷한 일을하는 것에 대해 Plyr. 재구성 패키지를 사용하여 동일한 작업을 수행하는 방법에 대해 Part 2를해야합니다. Plyr과 Reshape는 Hadley Wickham이 작성했으며 미친 유용한 도구입니다.

기본 R 기능으로 수행 할 수 있습니다.

n <- 100
test_data <- data.frame(
    var0 = rnorm(n),
    var1 = rnorm(n,1),
    var2 = rnorm(n,2),
    var3 = rnorm(n,3),
    var4 = rnorm(n,4),
    group = sample(letters[1:10],n,replace=TRUE),
    year = sample(c(2007,2009),n, replace=TRUE)
)

tapply(
    seq_len(nrow(test_data)),
    test_data$group,
    function(ind) sapply(
        c("var0","var1","var2","var3","var4"),
        function(x_name) tapply(
            test_data[[x_name]][ind],
            test_data$year[ind],
            mean
        )
    )
)

설명 :

  • 팁 : 랜덤 데이터를 생성 할 때 관측치 수를 정의하는 데 유용합니다. 샘플 크기를 변경하는 것은 더 쉽습니다.
  • 첫 번째 Tapply Split Row Index 1 : Nrow (Test_Data) 그룹 별,
  • 그런 다음 각 그룹에 대해 변수를 습격합니다
  • 고정 그룹 및 변수의 경우 매년 간단한 tapply returnig 평균 변수입니다.

r 2.9.2에서 결과는 다음과 같습니다.

$a
 var0.2007  var1.2007  var2.2007  var3.2007  var4.2007 
-0.3123034  0.8759787  1.9832617  2.7063034  4.1322758 

$b
            var0      var1     var2     var3     var4
2007  0.81366885 0.4189896 2.331256 3.073276 4.164639
2009 -0.08916257 1.5442126 3.008014 3.215019 4.398279

$c
          var0      var1     var2     var3     var4
2007 0.4232098 1.3657369 1.386627 2.808511 3.878809
2009 0.3245751 0.6672073 1.797886 1.752568 3.632318

$d
           var0      var1     var2     var3     var4
2007 -0.1335138 0.5925237 2.303543 3.293281 3.234386
2009  0.9547751 2.2111581 2.678878 2.845234 3.300512

$e
           var0      var1     var2     var3     var4
2007 -0.5958653 1.3535658 1.886918 3.036121 4.120889
2009  0.1372080 0.7215648 2.298064 3.186617 3.551147

$f
           var0      var1     var2     var3     var4
2007 -0.3401813 0.7883120 1.949329 2.811438 4.194481
2009  0.3012627 0.2702647 3.332480 3.480494 2.963951

$g
         var0       var1      var2     var3     var4
2007 1.225245 -0.3289711 0.7599302 2.903581 4.200023
2009 0.273858  0.2445733 1.7690299 2.620026 4.182050

$h
           var0     var1     var2     var3     var4
2007 -1.0126650 1.554403 2.220979 3.713874 3.924151
2009 -0.6187407 1.504297 1.321930 2.796882 4.179695

$i
            var0     var1     var2     var3     var4
2007  0.01697314 1.318965 1.794635 2.709925 2.899440
2009 -0.75790995 1.033483 2.363052 2.422679 3.863526

$j
           var0      var1     var2     var3     var4
2007 -0.7440600 1.6466291 2.020379 3.242770 3.727347
2009 -0.2842126 0.5450029 1.669964 2.747455 4.179531

임의의 데이터를 사용하면 "A"그룹에 문제가 있습니다. 2007 년 만 존재했습니다. 연도가 요인이되면 (2007 년과 2009 년 수준) 결과가 더 좋아 보일 수 있습니다 (매년 두 줄이 있지만 아마도 NA가있을 것입니다).

결과는 목록이므로 예를 들어 Lapply를 사용할 수 있습니다. 라텍스 테이블, HTML 테이블로 변환, 화면 전환 등에 인쇄하는 등으로 변환하십시오.

우선, CBIND를 사용할 필요는 없으므로 모든 것이 요인입니다. 이것은 작동합니다 :

test_data <- data.frame(
var0 = rnorm(100),
var1 = rnorm(100,1),
var2 = rnorm(100,2),
var3 = rnorm(100,3),
var4 = rnorm(100,4),
group = sample(letters[1:10],100,replace=T),
year = sample(c(2007,2009),100, replace=T))

둘째, 모범 사례는 사용하는 것입니다. " 변수 이름의 "_"대신. Google 스타일 가이드를 참조하십시오 (예를 들어).

마지막으로 Rigroup 패키지를 사용할 수 있습니다. 매우 빠릅니다. IGROUPMEANS () 함수를 적용하고 인덱스를 설정하십시오. i=as.factor(paste(test_data$group,test_data$year,sep="")). 나중에 이것의 예를 포함 시키려고 노력할 것입니다.

6/9/2017 편집

Cran에서 Rigroup 패키지가 제거되었습니다. 보다 이것

먼저 간단한 집계를 수행하여 요약하십시오.

df <- aggregate(cbind(var0, var1, var2, var3, var4) ~ year + group, test_data, mean)

그것은 이와 같은 데이터를 만듭니다 ...

   year group     var0      var1     var2     var3     var4
1  2007     a 42.25000 0.2031277 2.145394 2.801812 3.571999
2  2009     a 30.50000 1.2033653 1.475158 3.618023 4.127601
3  2007     b 52.60000 1.4564604 2.224850 3.053322 4.339109
...

그 자체로는 당신이 원하는 것과 매우 가깝습니다. 지금 그룹별로 분해 할 수 있습니다.

l <- split(df, df$group)

좋아, 그럼에도 불구하고 실제로 원한다면 출력을 개선 할 수 있습니다.

lapply(l, function(x) {d <- t(x[,3:7]); colnames(d) <- x[,2]; d})

$a
           2007      2009
var0 42.2500000 30.500000
var1  0.2031277  1.203365
var2  2.1453939  1.475158
...

그것은 당신의 모든 테이블 형식을 가지고 있지는 않지만 당신이 설명하는대로 정확하게 구성되어 있으며 가까이 있습니다. 이 마지막 단계는 당신이 좋아하는 방식을 예쁘게 할 수 있습니다.

이것은 요청 된 조직과 일치하는 유일한 대답이며, R. BTW에서 가장 빠른 방법입니다. 마지막 단계를 귀찮게하지 않고 집계에서 첫 번째 출력을 고수합니다. 분할.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top