각 그룹에 대해 데이터프레임의 모든 변수에 대한 평균을 요약합니다(ddply?나뉘다?)
문제
일주일 전에는 이 작업을 수동으로 수행했을 것입니다.그룹별로 데이터 프레임을 새 데이터 프레임으로 하위 집합합니다.각 데이터프레임에 대해 각 변수에 대한 평균을 계산한 다음 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에서 가장 빠른 방법입니다. 마지막 단계를 귀찮게하지 않고 집계에서 첫 번째 출력을 고수합니다. 분할.