데이터분석 전문가(ADP)를 위한 R프로그래밍 기초편7

factor로 집단을 정의하고 벡터를 factor에 의해 집단으로 분할

 

split(벡터, factor)함수를 이용

 

tapply(vec,factor,func)를 이용하여 집단별로 함수를 적용한다

 

> v <- c(24,23,52,46,75,25)
> w <- c(87,86,92,84,77,68)
> f <- factor(c('A','A','B','B','C','A'))
> groups <- split(v,f)
> groups
$A
[1] 24 23 25

$B
[1] 52 46

$C
[1] 75

> groups2 <- split(w,f)
> groups2
$A
[1] 87 86 68

$B
[1] 92 84

$C
[1] 77

> groups3 <- unstack(data.frame(v,f))
> groups3
$A
[1] 24 23 25

$B
[1] 52 46

$C
[1] 75

> tapply(v,f,mean)
 A  B  C 
24 49 75 

> tapply(w,f,sum)
  A   B   C 
241 176  77

 

 

데이터프레임을 여러 집단으로 분할하기

 

역시 split(벡터, factor)함수를 이용

 

library(MASS)

> head(Cars93[c('MPG.city','Origin')])
  MPG.city  Origin
1       25 non-USA
2       18 non-USA
3       20 non-USA
4       19 non-USA
5       22 non-USA
6       22     USA

> sp <- split(Cars93$MPG.city, Cars93$Origin)
> sp
$USA
 [1] 22 19 16 19 16 16 25 25 19 21 18 15 17 17 20 23 20 29 23 22 17 21 18 29 20 31 23 22 22 24 15 21 18 17 18 23 19 24 23 18 19
[42] 23 31 23 19 19 19 28

$`non-USA`
 [1] 25 18 20 19 22 46 30 24 42 24 29 22 26 20 17 18 18 29 28 26 18 17 20 19 29 18 29 24 17 21 20 33 25 23 39 32 25 22 18 25 17
[42] 21 18 21 20

> sp[[1]] #USA
 [1] 22 19 16 19 16 16 25 25 19 21 18 15 17 17 20 23 20 29 23 22 17 21 18 29 20 31 23 22 22 24 15 21 18 17 18 23 19 24 23 18 19
[42] 23 31 23 19 19 19 28

> median(sp[[1]])
[1] 20

 

리스트의 각 원소에 함수를 적용하기

 

lapply(list, func)하면 리스트로 반환하고

 

sapply(list, func)하면 벡터로 반환

 

> sp
$USA
 [1] 22 19 16 19 16 16 25 25 19 21 18 15 17 17 20 23 20 29 23 22 17 21 18 29 20 31 23 22 22 24 15 21 18 17 18 23 19 24 23 18 19
[42] 23 31 23 19 19 19 28

$`non-USA`
 [1] 25 18 20 19 22 46 30 24 42 24 29 22 26 20 17 18 18 29 28 26 18 17 20 19 29 18 29 24 17 21 20 33 25 23 39 32 25 22 18 25 17
[42] 21 18 21 20

> lapply(sp, mean)
$USA
[1] 20.95833

$`non-USA`
[1] 23.86667

> sapply(sp,median)
    USA non-USA 
     20      22

 

행렬에 함수를 적용하기

 

apply(mat, 1, func)하면 mat의 행별로 func를 적용

 

apply(mat,2,func)하면 mat의 열별로 func를 적용

 

> mat <- matrix(c(1,2,3,4,5,6,7,8,9),3,3)
> mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

> m1 <- apply(mat,1,sum)
> m1
[1] 12 15 18

> m2 <- apply(mat,2,mean)
> m2
[1] 2 5 8

 

 

데이터프레임에 함수 적용하기

 

lapply(df, FUN=func)

 

sapply(df, FUN=func)

 

apply(df, MARGIN=1, FUN=func)

 

apply(df, MARGIN=2, FUN=func)

 

lapply와 sapply는 MARGIN을 나타내는 1,2를 쓸필요없이 열단위로 func를 적용함

 

반면 apply는 반드시 MARGIN인자를 써야함

> df <- data.frame(x1=c(7,8,4,5,3), x2=c(9,1,2,3,4), x3=c(6,5,8,9,1))
> df
  x1 x2 x3
1  7  9  6
2  8  1  5
3  4  2  8
4  5  3  9
5  3  4  1

> dfm1 <- lapply(df,mean)
> dfm1
$x1
[1] 5.4

$x2
[1] 3.8

$x3
[1] 5.8

> dfm2 <- sapply(df,sum)
> dfm2
x1 x2 x3 
27 19 29 

> dfm3 <- apply(df,median)
Error in match.fun(FUN) : argument "FUN" is missing, with no default


> dfm3 <- apply(df, MARGIN=1,FUN=sum ##row
> dfm3
[1] 22 14 14 17  

> dfm4 <- apply(df,MARGIN=2, FUN=median) ##column
> dfm4
x1 x2 x3 
 5  3  6

 

by(df, factor, func)를 이용해서 데이터프레임에서 행별로 집단을 구분해서 함수를 적용한다

 

> df <- data.frame(x1=c(7,8,4,5,3), x2=c(9,1,2,3,4), x3=c(6,5,8,9,1))

> df
  x1 x2 x3
1  7  9  6
2  8  1  5
3  4  2  8
4  5  3  9
5  3  4  1

> f <- factor(c('A','A','B','B','C'))

> by(df,f,sum)
f: A
[1] 36
------------------------------------------------------------------------------------------------ 
f: B
[1] 31
------------------------------------------------------------------------------------------------ 
f: C
[1] 8

> by(df,f,sum)
f: A
[1] 36
------------------------------------------------------------------------------------------------ 
f: B
[1] 31
------------------------------------------------------------------------------------------------ 
f: C
[1] 8

 

 

by함수와 사용자정의함수 function(<paramter>) {-------} 이용해서 요인별로 선형회귀분석을 수행해볼 수 있다

 

by(df, factor, function(df){ lm(종속변수~설명변수, data=df) } )

 

> df <- iris

> f <- factor(iris$Species)

> by(df, f, function(df){lm(Sepal.Width~Sepal.Length+Petal.Length,data=df)})
f: setosa

Call:
lm(formula = Sepal.Width ~ Sepal.Length + Petal.Length, data = df)

Coefficients:
 (Intercept)  Sepal.Length  Petal.Length  
    -0.53038       0.80493      -0.04863  

------------------------------------------------------------------------------------------------ 
f: versicolor

Call:
lm(formula = Sepal.Width ~ Sepal.Length + Petal.Length, data = df)

Coefficients:
 (Intercept)  Sepal.Length  Petal.Length  
      0.8252        0.1455        0.2538  

------------------------------------------------------------------------------------------------ 
f: virginica

Call:
lm(formula = Sepal.Width ~ Sepal.Length + Petal.Length, data = df)

Coefficients:
 (Intercept)  Sepal.Length  Petal.Length  
     1.43799       0.22168       0.01361

 

mapply(func, vec1, vec2, vec3,............,)

 

mapply(func, list1, list2, list3,.............,)로 여러 벡터와 여러 리스트에 한꺼번에 func를 적용

 

> v <- c(24,23,52,46,75,25)
> w <- c(87,86,92,84,77,68)

> mapply(mean, v,w)
[1] 24 23 52 46 75 25

> mapply(factor,v,w)
[1] <NA> <NA> <NA> <NA> <NA> <NA>
Levels: 87 86 92 84 77 68

> list1 <- list(c(1,2,3,4,5,6),c(3,4,5,6),c(2,3,4,5))
> list1
[[1]]
[1] 1 2 3 4 5 6

[[2]]
[1] 3 4 5 6

[[3]]
[1] 2 3 4 5

> list2 <- list(c(4,2,3,1),c(2,3,41,2),c(3,4,1,2,3))
> list2
[[1]]
[1] 4 2 3 1

[[2]]
[1]  2  3 41  2

[[3]]
[1] 3 4 1 2 3

> mapply(sum,list1,list2)
[1] 31 66 27

 

sapply를 이용한 코딩

 

데이터프레임에서 타겟변수를 정하고

 

타겟변수와 설명변수간 상관계수를 sapply를 이용하여 구한다

 

상관계수가 높은 상위 10개의 변수를 입력변수로 선정(mask <- (rank(-abs(cors)) <= 10))

 

타겟변수와 입력변수로 다중회귀분석

df <- Cars93[c('Price','EngineSize', 'RPM', 'Weight')]

> cors <- sapply(df, cor, y=df$Price)

> cors
       Price   EngineSize          RPM       Weight 
 1.000000000  0.597425392 -0.004954931  0.647179005 
 
 > mask <- (rank(-abs(cors)) <= 10)
 
> mask
     Price EngineSize        RPM     Weight 
      TRUE       TRUE       TRUE       TRUE 
      
> best.pred <- df[,mask]

> head(best.pred)
  Price EngineSize  RPM Weight
1  15.9        1.8 6300   2705
2  33.9        3.2 5500   3560
3  29.1        2.8 5500   3375
4  37.7        2.8 5500   3405
5  30.0        3.5 5700   3640
6  15.7        2.2 5200   2880
 
 > lm(Price~. , best.pred)

Call:
lm(formula = Price ~ ., data = best.pred)

Coefficients:
(Intercept)   EngineSize          RPM       Weight  
 -51.793292     4.305387     0.007096     0.007271

 

 

 

참고

 

https://kkokkilkon.tistory.com/67

 

R apply 계열 함수 총 정리 1 ( apply / lapply / sapply / vapply )

apply 계열 함수 총 정리 1 ( apply / lapply / sapply / vapply ) apply 계열 함수는 주어진 함수 연산을 특정 단위로 쉽게 할 수 있도록 지원하는 함수 군이다. 어떤 함수이냐에 따라 1) 연산 대상 데이터의

kkokkilkon.tistory.com

 

 

TAGS.

Comments