R 에서 각 변수간 그룹의 평균값을 계산하여 새로운 열에 삽입해 보자

R 에서 각 변수간 그룹의 평균값을 계산하여 새로운 열에 삽입해 보자


아래와 같은 데이터가 있습니다.

treatment=rep(c("A","B","C","D","E"), each=3)
rep=rep(c("I","II","III"), time=5)
yield=c(10,11,21,13,23,23,13,13,5,33,21,13,42,12,13)
dataA=data.frame(treatment,rep, yield)

dataA
treatment rep yield
1 A I 10
2 A II 11
3 A III 21
4 B I 13
5 B II 23
6 B III 23
7 C I 13
8 C II 13
9 C III 5
10 D I 33
11 D II 21
12 D III 13
13 E I 42
14 E II 12
15 E III 13

이 데이터에서 treatment 별로 평균값을 계산하여 새로운 열에 삽입하고 싶습니다. 그래서 아래와 같은 코드를 사용해 보겠습니다.

dataA$mean= NA #to create an empty column

dataA$mean[dataA$treatment=="A"]=mean(dataA$yield[dataA$treatment=="A"], na.rm=TRUE)
dataA$mean[dataA$treatment=="B"]=mean(dataA$yield[dataA$treatment=="B"], na.rm=TRUE)
dataA$mean[dataA$treatment=="C"]=mean(dataA$yield[dataA$treatment=="C"], na.rm=TRUE)
dataA$mean[dataA$treatment=="D"]=mean(dataA$yield[dataA$treatment=="D"], na.rm=TRUE)
dataA$mean[dataA$treatment=="E"]=mean(dataA$yield[dataA$treatment=="E"], na.rm=TRUE)

dataA
treatment rep yield mean
1 A I 10 14.00000
2 A II 11 14.00000
3 A III 21 14.00000
4 B I 13 19.66667
5 B II 23 19.66667
6 B III 23 19.66667
7 C I 13 10.33333
8 C II 13 10.33333
9 C III 5 10.33333
10 D I 33 22.33333
11 D II 21 22.33333
12 D III 13 22.33333
13 E I 42 22.33333
14 E II 12 22.33333
15 E III 13 22.33333


하지만 이 코드는 너무 길어 보입니다. 아주 간편하게 위와 동일한 계산을 수행하는 코드가 있으면 아주 편할것 같습니다. tapply() 코드는 위와 동일한 계산을 가능하게 하는 코드입니다. mean2 라는 열을 생성해서 그곳에 각 변수의 평균값을 계산하여 삽입하고 싶습니다.

library(base)
dataA$mean2=tapply(dataA$yield, dataA$treatment, mean, na.rm=TRUE)[dataA$treatment]

dataA
treatment rep yield mean mean2
1 A I 10 14.00000 14.00000
2 A II 11 14.00000 14.00000
3 A III 21 14.00000 14.00000
4 B I 13 19.66667 19.66667
5 B II 23 19.66667 19.66667
6 B III 23 19.66667 19.66667
7 C I 13 10.33333 10.33333
8 C II 13 10.33333 10.33333
9 C III 5 10.33333 10.33333
10 D I 33 22.33333 22.33333
11 D II 21 22.33333 22.33333
12 D III 13 22.33333 22.33333
13 E I 42 22.33333 22.33333
14 E II 12 22.33333 22.33333
15 E III 13 22.33333 22.33333

첫번째 일일이 계산했던 방법과 동일한 값을 얻을 수 있습니다. 즉, 아래와 같이 길었던 코드와 동일한 계산식을 제공하는 코드가 tapply() 입니다.

dataA$mean[dataA$treatment=="A"]=mean(dataA$yield[dataA$treatment=="A"], na.rm=TRUE)
dataA$mean[dataA$treatment=="B"]=mean(dataA$yield[dataA$treatment=="B"], na.rm=TRUE)
dataA$mean[dataA$treatment=="C"]=mean(dataA$yield[dataA$treatment=="C"], na.rm=TRUE)
dataA$mean[dataA$treatment=="D"]=mean(dataA$yield[dataA$treatment=="D"], na.rm=TRUE)
dataA$mean[dataA$treatment=="E"]=mean(dataA$yield[dataA$treatment=="E"], na.rm=TRUE)
                                       ↓
dataA$mean2=tapply(dataA$yield, dataA$treatment, mean, na.rm=TRUE)[dataA$treatment]


만일 변수가 하나가 아니라 여러개일 경우 그 변수간 조합의 평균을 계산하고 싶을 때는 어떻게 해야 할까요?

treatment=rep(rep(c("A","B","C","D","E"), each=3),2)
rep=rep(rep(c("I","II","III"), time=5),2)
environment=rep(c("East","West","North"), each=10)
yield=c(10,11,21,13,23,23,13,13,5,33,21,13,42,12,13,10,11,54,45,39,33,29,43,55,33,24,32,42,28,43)
dataA=data.frame(treatment,rep, environment, yield)

dataA
treatment rep environment yield mean
1 A I East 10 14.00000
2 A II East 11 14.00000
3 A III East 21 14.00000
4 B I East 13 19.66667
5 B II East 23 19.66667
6 B III East 23 19.66667
7 C I East 13 10.33333
8 C II East 13 10.33333
9 C III East 5 10.33333
10 D I East 33 33.00000
11 D II West 21 17.00000
12 D III West 13 17.00000
13 E I West 42 22.33333
14 E II West 12 22.33333
15 E III West 13 22.33333
16 A I West 10 25.00000
17 A II West 11 25.00000
18 A III West 54 25.00000
19 B I West 45 42.00000
20 B II West 39 42.00000
21 B III North 33 33.00000
22 C I North 29 42.33333
23 C II North 43 42.33333
24 C III North 55 42.33333
25 D I North 33 29.66667
26 D II North 24 29.66667
27 D III North 32 29.66667
28 E I North 42 37.66667
29 E II North 28 37.66667
30 E III North 43 37.66667

이제는 treatment 와 environment 간 조합 (i.e., A and East) 의 평균을 구하고 싶습니다. 아래와 같이 코드를 작성합니다.

library(base)
dataA$mean=tapply(dataA$yield, list(dataA$treatment, dataA$environment), mean, na.rm=TRUE)[cbind(dataA$treatment, dataA$environment)]

dataA
treatment rep environment yield mean
1 A I East 10 14.00000
2 A II East 11 14.00000
3 A III East 21 14.00000
4 B I East 13 19.66667
5 B II East 23 19.66667
6 B III East 23 19.66667
7 C I East 13 10.33333
8 C II East 13 10.33333
9 C III East 5 10.33333
10 D I East 33 33.00000
11 D II West 21 17.00000
12 D III West 13 17.00000
13 E I West 42 22.33333
14 E II West 12 22.33333
15 E III West 13 22.33333
16 A I West 10 25.00000
17 A II West 11 25.00000
18 A III West 54 25.00000
19 B I West 45 42.00000
20 B II West 39 42.00000
21 B III North 33 33.00000
22 C I North 29 42.33333
23 C II North 43 42.33333
24 C III North 55 42.33333
25 D I North 33 29.66667
26 D II North 24 29.66667
27 D III North 32 29.66667
28 E I North 42 37.66667
29 E II North 28 37.66667
30 E III North 43 37.66667

treatment A 와 West 에서의 평균이 과연 25가 맞는지 검증해 보겠습니다.

mean (dataA$yield[dataA$treatment=="A" & dataA$environment=="West"], na.rm=TRUE)
# 25

평균값은 25 라고 합니다. 위에서 tapply() 코드로 계산된 값과 동일한 값 입니다.


Step-by-Step Guide to Calculating and Adding Variable Means in R



Leave a Reply

If you include a website address in the comment section, I cannot see your comment as it will be automatically deleted and will not be posted. Please refrain from including website addresses.