apply 계열 함수는 array, data frame, vector 등 에 대해 함수를 적용하는
경우에 편리하게 사용하는 함수 이다. 통상 각데이터 연산을 할때 for문을
사용하는 것 보다 빠르게 연산을 한다.
함수 비고
종류 |
사용법 |
apply |
apply(X, MARGIN, FUN, …, simplify = TRUE) |
lapply |
lapply(X, FUN, …) ,MARGIN 인자는 필요없음 단지 열기준(y축기준) 으로 만 적용됨 |
sapply |
sapply , lapply의 간단형태, simplify=FALSE로 세팅하면 lapply와 유사 |
tapply |
tapply(X, INDEX, FUN = NULL, …, default = NA, simplify = TRUE) , 범주형변수를 다루는데 유용 |
by |
by(data, INDICES, FUN, …, simplify = TRUE) , by 함수와 유사 |
apply 함수
Input type |
output type |
Matrix, Array, Data frame |
Vector, matrix, array or list |
- data frame으로 리턴 안됨, list는 input을 사용안됨
# matrix array 에 적용
> x <- cbind(x1 = 3, x2 = c(10:14, 20:24))
> x
## x1 x2
## [1,] 3 10
## [2,] 3 11
## [3,] 3 12
## [4,] 3 13
## [5,] 3 14
## [6,] 3 20
## [7,] 3 21
## [8,] 3 22
## [9,] 3 23
## [10,] 3 24
# 주로 행기준(x축기준) 연산에 적용
> apply(x,1,function(x){ x }) # 행 기준으로 ft 적용
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## x1 3 3 3 3 3 3 3 3 3 3
## x2 10 11 12 13 14 20 21 22 23 24
> apply(x,2:1,function(x){ x }) # apply(x,c(2,1),function(x){ x }) 동일 (원소별 적용)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## x1 3 3 3 3 3 3 3 3 3 3
## x2 10 11 12 13 14 20 21 22 23 24
> apply(x,1, function(x){ sum(x) } ) # apply(x,1,sum) 동일표현, x[,1]+x[,2] 와 동일함
## [1] 13 14 15 16 17 23 24 25 26 27
> apply(x,2:1,sum) # 원소별 합산 그대로 출력
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## x1 3 3 3 3 3 3 3 3 3 3
## x2 10 11 12 13 14 20 21 22 23 24
# 주로 열기준(y축기준) 연산에 적용
> apply(x,2,function(x){ x }) # 열 기준으로 ft 적용
## x1 x2
## [1,] 3 10
## [2,] 3 11
## [3,] 3 12
## [4,] 3 13
## [5,] 3 14
## [6,] 3 20
## [7,] 3 21
## [8,] 3 22
## [9,] 3 23
## [10,] 3 24
> apply(x,1:2,function(x){ x }) # apply(x,c(1,2),function(x){ x }) 동일 (원소별 적용)
## x1 x2
## [1,] 3 10
## [2,] 3 11
## [3,] 3 12
## [4,] 3 13
## [5,] 3 14
## [6,] 3 20
## [7,] 3 21
## [8,] 3 22
## [9,] 3 23
## [10,] 3 24
> apply(x,2, function(x){ sum(x) } ) # 열기준 합산 , c(x1=sum(x[,1]), x2=sum(x[,2])) 와 동일함
> apply(x,2,function(param){ param + x[,1] })[,2] # 각 컬럼에 첫번째 컬럼을 더해서 2번째 컬럼만 출력
## [1] 13 14 15 16 17 23 24 25 26 27
> apply(x,1:2,sum) # 원소별 합산 그대로 출력
## x1 x2
## [1,] 3 10
## [2,] 3 11
## [3,] 3 12
## [4,] 3 13
## [5,] 3 14
## [6,] 3 20
## [7,] 3 21
## [8,] 3 22
## [9,] 3 23
## [10,] 3 24
# 원소별 적용
> apply(x,c(2,1),function(x){ x })
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## x1 3 3 3 3 3 3 3 3 3 3
## x2 10 11 12 13 14 20 21 22 23 24
lapply 함수 ( apply 와의 차이는 output 형식과 Margin 지정이 없는것)
- list 적용 함수로 lapply와 rapply가 있다( 차이는 lapply는 컬럼별 함수 적용, rapply 구성요소 하나하나 함수 적용)
Input type |
output type |
Vector ,List ,Data frame |
list |
# list 적용예제
> list1<-list(maths=c(64,45,89,67),english=c(79,84,62,80),physics=c(68,72,69,80),chemistry = c(99,91,84,89))
> lapply(list1,mean) # column 별(즉 키별로 group by 개념과 비슷) 평균 산출
## $maths
## [1] 66.25
##
## $english
## [1] 76.25
##
## $physics
## [1] 72.25
##
## $chemistry
## [1] 90.75
> class(lapply(list1,mean)) # return value type 확인
> lapply(list1,function(x) { x + 100 }) # 각 원소에 100 더함
## $maths
## [1] 164 145 189 167
##
## $english
## [1] 179 184 162 180
##
## $physics
## [1] 168 172 169 180
##
## $chemistry
## [1] 199 191 184 189
# 각 원소에 100 더함 , rapply 비교 - 결과는 구성요소 하나하나 나오게됨
# rapply(list1,function(x) { x + 100 }, how="list") 옵션을 주게 되면 동일함
> rapply(list1,function(x) { x + 100 })
maths1 maths2 maths3 maths4 english1 english2 english3 english4 physics1 physics2 physics3 physics4 chemistry1 chemistry2
164 145 189 167 179 184 162 180 168 172 169 180 199 191 chemistry3 chemistry4
184 189
# data frame 적용예제
> ratings <- c(4.2, 4.4, 3.4, 3.9, 5, 4.1, 3.2, 3.9, 4.6, 4.8, 5, 4, 4.5, 3.9, 4.7, 3.6)
> employee.mat <- matrix(ratings,byrow=TRUE,nrow=4,dimnames = list(c("Q1","Q2","Q3","Q4"),c("Kari","Thri","Smith","Jane")))
> employee <- as.data.frame(employee.mat)
> employee
## Kari Thri Smith Jane
## Q1 4.2 4.4 3.4 3.9
## Q2 5.0 4.1 3.2 3.9
## Q3 4.6 4.8 5.0 4.0
## Q4 4.5 3.9 4.7 3.6
> lapply(employee,cumsum) # column별 누적합계
## $Kari
## [1] 4.2 9.2 13.8 18.3
##
## $Thri
## [1] 4.4 8.5 13.3 17.2
##
## $Smith
## [1] 3.4 6.6 11.6 16.3
##
## $Jane
## [1] 3.9 7.8 11.8 15.4
#사용자 정의로 행 수만큼 loop가 도는지 확인
> count = 0 #전역변수 선언
> printft<-function(x) { count <<- count + 1 } # 함수안에서 전역변수 변경은 <<- 로 해야함
> lapply(employee,printft)
## $Kari
## [1] 1
##
## $Thri
## [1] 2
##
## $Smith
## [1] 3
##
## $Jane
## [1] 4
> classft<-function(x) { class(x) } #클래스 확인
> lapply(employee,printft) # y축에 해당하는 데이타 타입
## $Kari
## [1] 5
##
## $Thri
## [1] 6
##
## $Smith
## [1] 7
##
## $Jane
## [1] 8
#사용자정의함수적용
> passft<-function(x) {
return ( if( x[[1]]>4.2)
{ 'pass'}
else
{ 'failure'}
)
}
> lapply(employee,passft)
## $Kari
## [1] "failure"
##
## $Thri
## [1] "pass"
##
## $Smith
## [1] "failure"
##
## $Jane
## [1] "failure"
> passft<-function(x) {
return ( ifelse( x > 4.2,"Pass","Failure" )) # column 데이터 배열이 들어오기 때문에 column 비교 함수를 적용해야함
}
> lapply(employee,passft) # 사용자 정의함수 적용
## $Kari
## [1] "Failure" "Pass" "Pass" "Pass"
##
## $Thri
## [1] "Pass" "Failure" "Pass" "Failure"
##
## $Smith
## [1] "Failure" "Failure" "Pass" "Pass"
##
## $Jane
## [1] "Failure" "Failure" "Failure" "Failure"
> check <- function(x) {
return (x[x>4.2])
}
> lapply(employee,check) # 사용자 정의함수 적용
## $Kari
## [1] 5.0 4.6 4.5
##
## $Thri
## [1] 4.4 4.8
##
## $Smith
## [1] 5.0 4.7
##
## $Jane
## numeric(0)
sapply 함수
Input type |
output type |
Vector ,List ,Data frame |
Vector, matrix, array or list |
> sapply(employee,mean) # lapply 와의 차이점은 lapply 리턴은 list, sapply의 리턴은 Vector
## Kari Thri Smith Jane
## 4.575 4.300 4.075 3.850
> sapply(employee,mean,simplify=FALSE ) # lapply 와 동일하게 된다.
## $Kari
## [1] 4.575
##
## $Thri
## [1] 4.3
##
## $Smith
## [1] 4.075
##
## $Jane
## [1] 3.85
> sapply(employee,passft) # 사용자 정의함수 적용
## Kari Thri Smith Jane
## [1,] "Failure" "Pass" "Failure" "Failure"
## [2,] "Pass" "Failure" "Failure" "Failure"
## [3,] "Pass" "Pass" "Pass" "Failure"
## [4,] "Pass" "Failure" "Pass" "Failure"
tapply 함수
-
- tapply(column 1, column 2, FUN) ,column1 : numeric column , column2
- factor obejct
> salary <- c(2150000,2970000,3240000,3490000,4520000)
> allowance <- c(200000,300000,300000,300000,400000)
> designation<-c("초급","중급","중급","중급","관리자")
> gender <- c("M","F","F","M","M")
> tapply(salary,designation,mean)
## 관리자 중급 초급
## 4520000 3233333 2150000
# 사용자 Function
> userft<-function(x) {
return ( ifelse( x >= 2500000,"250만 이상","250만 미만" )) # column 데이터 배열이 들어오기 때문에 column 비교 함수를 적용해야함
}
> tapply(salary,designation,userft)
## $관리자
## [1] "250만 이상"
##
## $중급
## [1] "250만 이상" "250만 이상" "250만 이상"
##
## $초급
## [1] "250만 미만"
by 함수
> by(salary,designation,mean) # 리턴값이 tapply array 이고 by 는 by class
## designation: 관리자
## [1] 4520000
## ------------------------------------------------------------
## designation: 중급
## [1] 3233333
## ------------------------------------------------------------
## designation: 초급
## [1] 2150000
> by(salary,list(designation,gender),mean)
## : 관리자
## : F
## [1] NA
## ------------------------------------------------------------
## : 중급
## : F
## [1] 3105000
## ------------------------------------------------------------
## : 초급
## : F
## [1] NA
## ------------------------------------------------------------
## : 관리자
## : M
## [1] 4520000
## ------------------------------------------------------------
## : 중급
## : M
## [1] 3490000
## ------------------------------------------------------------
## : 초급
## : M
## [1] 2150000
> by(list(salary,allowance) ,designation,colMeans)
## designation: 관리자
## c.2150000..2970000..3240000..3490000..4520000.
## 4520000
## c.2e.05..3e.05..3e.05..3e.05..4e.05.
## 400000
## ------------------------------------------------------------
## designation: 중급
## c.2150000..2970000..3240000..3490000..4520000.
## 3233333
## c.2e.05..3e.05..3e.05..3e.05..4e.05.
## 300000
## ------------------------------------------------------------
## designation: 초급
## c.2150000..2970000..3240000..3490000..4520000.
## 2150000
## c.2e.05..3e.05..3e.05..3e.05..4e.05.
## 200000
> by(salary,designation,userft)
## designation: 관리자
## [1] "250만 이상"
## ------------------------------------------------------------
## designation: 중급
## [1] "250만 이상" "250만 이상" "250만 이상"
## ------------------------------------------------------------
## designation: 초급
## [1] "250만 미만"
> by(salary,list(designation,gender),userft)
## : 관리자
## : F
## NULL
## ------------------------------------------------------------
## : 중급
## : F
## [1] "250만 이상" "250만 이상"
## ------------------------------------------------------------
## : 초급
## : F
## NULL
## ------------------------------------------------------------
## : 관리자
## : M
## [1] "250만 이상"
## ------------------------------------------------------------
## : 중급
## : M
## [1] "250만 이상"
## ------------------------------------------------------------
## : 초급
## : M
## [1] "250만 미만"
댓글남기기