Plyr package (데이터 조작)
plyr
는 reshape2
와 마찬가지로 Hadley Wickham
에 의해서 개발 되었다.
2011년에 해당 논문이 아래와 같이 출간되었다.
The split-apply-combine strategy for data analysis(2011, Journal of Statistical Software, Vol 40).
데이터들을 쪼개고, 일부부늘 취하며, 어떤 특정 함수를 특정 부분에 적용하고
그리고 결과들을 조합하는 향상된 기능을 제공하는 패키지이다.
그 밖에도
loop의 재배치를 제공한다.
로드법
install.packages("plyr")
library(plyr)
apply 종류가 많다. 하지만 데이터 프레임을 위한것은 없다.
이때 plyr package에 있는 ddply를 이용한다.
함수 제공 형태
- 배열(a)
- 데이터 프레임(d)
- 리스트(l)
_
는 아무런 출력도 내보내지 않음을 의미함.
{adl} | {adl_} | ply |
---|---|---|
입력 데이터 타입 | 출력 데이터 타입 |
유용한 함수: adply()
, ddply()
, mdply()
유용한 유틸리티 함수: transform()
, mutate()
, summarise()
, subset()
Adply()
Adply()
는 배열(a)를 받아 데이터 프레임(d)을 반환하는 함수이다.
입력이 반드시 배열일 필요는 없고 숫자 색인으로 접근 가능 하기만 하면된다.
따라서 데이터 프레임도 입력으로 사용이 가능하다.
apply()의 단점인 문자열 데이터가 섞여 있다면 데이터가 모두 문자열로 반환된다는 점을 개선한 것이다.
adply(
.data, # 행렬, 배열, 또는 데이터 프레임
# 함수를 적용할 방향. 1(행 방향), 2(열 방향) 또는 c(1,2) 행과 열의 모든 방향을 지정 한다.
.margins,
.fun=NULL # .margin 방향으로 잘려진 데이터에 적용할 함수
반환 값은 데이터 프레임이다.
apply
와 유사하지만 반환 값이 데이터 프레임이라는 차이가 있다.
예제
#적용 전
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
adply(iris, 1 , function(row){ row$Sepal.Length >= 5.0 & row$Species == "setosa"})
Sepal.Length Sepal.Width Petal.Length Petal.Width Species V1
1 5.1 3.5 1.4 0.2 setosa TRUE
2 4.9 3.0 1.4 0.2 setosa FALSE
3 4.7 3.2 1.3 0.2 setosa FALSE
예제: 컬럼에 이름 부여
adply(iris, 1 , function(row)
{
data.frame( sepal_ge_5_setosa = c(row$Sepal.Length >= 5.0 & row$Species == "setosa"))
}
)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species sepal_ge_5_setosa
1 5.1 3.5 1.4 0.2 setosa TRUE
2 4.9 3.0 1.4 0.2 setosa FALSE
Ddply()
ddply()는 데이터 프레임(d)을 입력으로 받아 데이터 프레임(d)을 내보내는 함수 이다.
ddply(
.data,
.variables, #데이터를 그룹 지을 변수명
.fun=NULL
)
반환 값은 데이터 프레임이다.
adply()
와 ddply()
의 가장 큰 차이점이라면 adply()
는 행 또는 컬럼 단위로 함수를 적용하는 반면ddply()
는 .variables
에 나열한 컬럼에 따라 데이터를 나눈 뒤 함수를 적용한다는 점이다.
아래와 같이.()안의 컬럼으로 데이터를 묶은 다음에 function
안에 있는 함수를 적용 하게 된다.
데이터 프레임의 컬럼의 이름은 sepal.width.mean
이며, 각 Species
에 대해서 묶고 그것들의 Sepal.Width
의 평균을 구하는 코드이다.
ddply(iris, .(Species), function(sub){
data.frame(sepal.width.mean = mean(sub$Sepal.Width))
})
Species sepal.width.mean
1 setosa 3.428
2 versicolor 2.770
3 virginica 2.974
추가 조건을 기입한 예제는 아래와 같다.
ddply(iris, .(Species, Sepal.Length > 5.0), function(sub){
data.frame(sepal.width.mean = mean(sub$Sepal.Width))
})
Species Sepal.Length > 5 sepal.width.mean
1 setosa FALSE 3.203571
2 setosa TRUE 3.713636
3 versicolor FALSE 2.233333
4 versicolor TRUE 2.804255
5 virginica FALSE 2.500000
6 virginica TRUE 2.983673
Mdply()
m{adl_}ply()
, 즉 maply()
, mdply()
, mlply()
, m_ply()
함수는 데이터 프레임 또는
배열을 인자로 받아 각 컬럼을 주어진 함수에 적용하고 그 실행 결과들을 조합한다.
여기서는 이들 중 mdply()
에 대해서 살펴본다.
plyr::mdply(
.data, # 인자로 사용할 행렬 또는 데이터 프레임
.fun, # 호출할 함수
)
# 반환 값은 데이터 프레임이다.
Transform, Mutate, Summarise, Subset
데이터 프레임을 반환 한다.
base::transform(
.data # 변환할 객체
... # 태그=값 형태의 인자들
)
데이터 프레임 _data에 ...에 지정한 연산을 수행한 뒤 그 결과를 지정한 새로운 컬럼을 추가한 데이터 프레임을 반환한다.
데이터 프레임에 새로운 컬럼을 추가하거나 기존 컬럼을 수정 한다.
plyr::mutate(
.data, # 변환할 데이터 프레임
... # 새로운 컬럼 정의. 컬럼명 = 값 형식
)
변환이 이루어진다는 점은 transform()
과 같지만 컬럼명=값 형태로 지정된 연산이 여러 개 있을 때 앞서의 연산 결과를 뒤에 나오는 연산에서 참조할 수 있다는 차이가 있다.
plyr:summarise: 데이터 프레임을 요약 한다.
plyr::summarise(
.data, # 요약할 데이터 프레임
... # 변수=값 형태의 인자들
)
...에 지정된 그룹마다의 요약을 수행한 뒤 그 결과를 저장한 새로운 컬럼이 추가된 데이터 프레임을 반환한다.
Transform()
transform
은 연산 결과를 데이터 프레임의 새로운 컬럼에 저장하는 함수이다.
이를 사용해 baseball
데이터에 각 행이 선수의 몇 년차 통계인지를 뜻하는 cyear
컬럼을 추가해보자.
다음 코드는 데이터를 선수id
로 분할하여 그룹 지은 뒤, 각 그룹에세 year
의 최솟값과 현재 행의 year
값의 차이를 cyear
에 저장 한다.
> head(ddply(baseball, .(id), transform, cyear = year - min(year) + 1))
id year stint team lg g ab r h X2b X3b hr rbi sb cs bb so ibb hbp sh sf gidp cyear
1 aaronha01 1954 1 ML1 NL 122 468 58 131 27 6 13 69 2 2 28 39 NA 3 6 4 13 1
2 aaronha01 1955 1 ML1 NL 153 602 105 189 37 9 27 106 3 1 49 61 5 3 7 4 20 2
3 aaronha01 1956 1 ML1 NL 153 609 106 200 34 14 26 92 2 4 37 54 6 2 5 7 21 3
4 aaronha01 1957 1 ML1 NL 151 615 118 198 27 6 44 132 1 1 57 58 15 0 0 3 13 4
5 aaronha01 1958 1 ML1 NL 153 601 109 196 34 4 30 95 4 1 59 49 16 1 0 3 21 5
6 aaronha01 1959 1 ML1 NL 154 629 116 223 46 7 39 123 8 0 51 54 17 4 0 9 19 6
Mutate()
base::transform()
을 개선한 plyr::mutate()
함수가 있다. 이 함수는 여러 컬럼을 데이터 프레임에 추가할 때 바로 앞서 추가한 컬럼을 뒤에 추가하는 컬럼에서 참조할 수 있어 편리하다. 예를 들어, 아래 코드에서 muate()
를 이용해 transform()
예에서처럼 cyear
를 계산한 뒤log(cyear)
를 log_cyear
컬럼으로 추가 한다.
만약 mutate()
가 아닌 transform()
을 사용하면 이 경우 에러가 발생 한다.
> head( ddply(baseball, .(id), mutate, cyear=year - min(year)+1, log_cyear = log(cyear)))
>
id year stint team lg g ab r h X2b X3b hr rbi sb cs bb so ibb hbp sh sf gidp cyear log_cyear
1 aaronha01 1954 1 ML1 NL 122 468 58 131 27 6 13 69 2 2 28 39 NA 3 6 4 13 1 0.0000000
2 aaronha01 1955 1 ML1 NL 153 602 105 189 37 9 27 106 3 1 49 61 5 3 7 4 20 2 0.6931472
3 aaronha01 1956 1 ML1 NL 153 609 106 200 34 14 26 92 2 4 37 54 6 2 5 7 21 3 1.0986123
4 aaronha01 1957 1 ML1 NL 151 615 118 198 27 6 44 132 1 1 57 58 15 0 0 3 13 4 1.3862944
5 aaronha01 1958 1 ML1 NL 153 601 109 196 34 4 30 95 4 1 59 49 16 1 0 3 21 5 1.6094379
6 aaronha01 1959 1 ML1 NL 154 629 116 223 46 7 39 123 8 0 51 54 17 4 0 9 19 6 1.7917595
Summarise()
transform
이 인자로 주어진 계산 결과를 새로운 컬럼에 추가한 데이터 프레임을 반환하는 반면,summarise()
는 계산 결과만을 담은 새로운 데이터 프레임을 반환 한다.
baseball 데이터에서 각 선수의 최초 데이터가 몇 년도인지를 조사해보자.
아래 예에서는 데이터를 id마다 그룹지은 뒤 각 그룹마다 year의 최솟값을 계산한 minyear 컬럼을 생성 했다.
연산 시 사용할 함수로 summarise()
를 지정했으므로 그룹을 짓는 변수인 id와 각 그룹의 요약 값 minyear만 저장된 데이터 프레임이 반환됐다.
> head (ddply(baseball, .(id), summarise, minyear=min(year)))
id minyear
1 aaronha01 1954
2 abernte02 1955
3 adairje01 1958
4 adamsba01 1906
5 adamsbo03 1946
6 adcocjo01 1950
만약 여러 요약 값을 구하고 싶다면 요약 값 계산을 계속 나열한다.
> head (ddply(baseball, .(id), summarise, minyear=min(year), maxyear=max(year)))
id minyear maxyear
1 aaronha01 1954 1976
2 abernte02 1955 1972
3 adairje01 1958 1970
4 adamsba01 1906 1926
5 adamsbo03 1946 1959
6 adcocjo01 1950 1966
'AI > R Basic' 카테고리의 다른 글
Apply 함수 (데이터 조작) (1) | 2015.10.03 |
---|---|
R의 문자열 처리 및 비교 (0) | 2015.10.03 |
Reshape2 pacakge (데이터 조작) (0) | 2015.10.01 |
R 자주 사용하는 팁 및 한글 주석 깨짐 해결 (2) | 2015.07.30 |
R의 철학 (0) | 2015.04.17 |