R 핵심만 배우기 #4 - 데이터 프레임 2번째
- -
R 핵심 문법 #4 - data.frame 2번째
양호성
데이터 프레임 다루기
지금까지 배웠던 자료구조들을 토대로 데이터를 다루는 것을 조금씩 해보겠습니다.
data.frame 에서 row / column 추가하기
- 두 벡터를 각각 row로 하는 dataframe을 만들고 싶으면? : rbind
vec1 <- c('one','two','three')
vec2 <- c(1,2,3)
rbind(vec1, vec2)
## [,1] [,2] [,3]
## vec1 "one" "two" "three"
## vec2 "1" "2" "3"
data.frame(rbind(vec1,vec2))
## X1 X2 X3
## vec1 one two three
## vec2 1 2 3
- 이번에는, 두 벡터를 각각 column으로 하는 dataframe을 만들고 싶으면? : cbind
vec1 <- c('one','two','three')
vec2 <- c(1,2,3)
cbind(vec1, vec2)
## vec1 vec2
## [1,] "one" "1"
## [2,] "two" "2"
## [3,] "three" "3"
df <- data.frame(cbind(vec1,vec2))
str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ vec1: Factor w/ 3 levels "one","three",..: 1 3 2
## $ vec2: Factor w/ 3 levels "1","2","3": 1 2 3
- 그런데 위의 방법은 str(df)에서 보듯이, 숫자든, 문자든 모두 factor로 인식하게 됩니다. 그럴땐, cbind.data.frame이라는 함수를 사용합니다.
cbind.data.frame(vec1, vec2)
## vec1 vec2
## 1 one 1
## 2 two 2
## 3 three 3
df <- cbind.data.frame(vec1, vec2, stringsAsFactors = F)
str(df)
## 'data.frame': 3 obs. of 2 variables:
## $ vec1: chr "one" "two" "three"
## $ vec2: num 1 2 3
apply 함수 이해하기
행렬 혹은 data.frame에서 각 row, column에 대해 평균을 계산한다든지, 특정 함수를 적용하고 싶을 때가 있죠. 이럴 때, 가장 기본적으로 생각하는 게 for loop를 활용하여 각 row(혹은 column) 별로 함수를 적용합니다.
예를 들어,
mat <- matrix(c(1,2,3,4,5,6,7,8,9), nrow=3)
#각 row의 평균을 계산하고 싶다면
for (i in seq(1:nrow(mat))){
print(mean(mat[i,]))
}
## [1] 4
## [1] 5
## [1] 6
그런데 많은 양의 데이터를 for loop 하는 것은 비효율적입니다. 매번 for loop를 돌때마다 함수를 불러와야 하기 때문이죠. 따라서 최대한 for loop를 줄이는 것이 중요합니다!! 그 때 사용하는 함수가 바로 apply입니다. apply는 한 번만 함수를 불러와서 모든 데이터에 적용하기 때문에 훨씬 시간을 줄일 수 있습니다.
mat <- matrix(c(1,2,3,4,5,6,7,8,9), nrow=3)
apply(mat, 1, mean) #mean이라는 함수를 row(1)로 적용
## [1] 4 5 6
apply(mat, 2, mean) #mean이라는 함수를 column(2) 별로 적용
## [1] 2 5 8
apply(mat, 1, range) #range 함수는 각행의 최소, 최댓값 2개를 반환함
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 7 8 9
Quiz
iris 데이터 셋에 적용해보자
- apply를 활용하여 iris의 Species를 제외한 4개 변수에 대해 평균을 아래와 같이 계산하세요.
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## 5.843333 3.057333 3.758000 1.199333
- apply를 활용하여 Sepal.Length, Sepal.Width의 최소, 최대값을 아래와 같이 구하세요. (최소, 최댓값을 구하는 함수는 range)
## Sepal.Length Sepal.Width
## [1,] 4.3 2.0
## [2,] 7.9 4.4
list, vector에 대한 for loop 계산
데이터 프레임과 마찬가지로 list, vector에 대해서도 for loop를 최소화 하는 것이 좋습니다. 대신, apply와 비슷하게 lapply, sapply를 사용합니다. 좀 더 구체적으로 예를 들어보면, 리스트 (1,2,3)을 제곱한 값을 반환하고 싶다고 합시다. 그래서 아래와 같이 계산하면 실행이 안되죠. list는 vector처럼 연산 함수가 적용되지 않습니다.
lst <- list(1,2,3)
lst
lst^2
이럴때, for loop를 쓰지 말고, apply의 사촌격인 lapply, sapply를 사용합니다.
lapply(벡터 혹은 리스트, 함수)
sapply(벡터 혹은 리스트, 함수)
앞에 예를 들었듯이, 벡터 c(1,2,3)을 제곱하고 싶다면,
#lapply 이용하면
lst <- list(1,2,3)
lapply(lst, function(x){x^2})
## [[1]]
## [1] 1
##
## [[2]]
## [1] 4
##
## [[3]]
## [1] 9
근데 lapply는 결과값이 list로 나오기 때문에, 벡터로 나오게 하고 싶다면 sapply를 이용하면 됩니다.
sapply(lst, function(x){x^2})
## [1] 1 4 9
- lapply, sapply도 data.frame 에 적용할 수 있는데, apply는 결과값이 data.frame인 반면, lapply, sapply는 결과값이 각각 list, vector 라는 차이가 있습니다. 그리고 기본적으로 각 column에 대해 함수가 적용됩니다.
lst <- lapply(iris[,1:4], sum)
class(lst)
## [1] "list"
vec <- sapply(iris[,1:4], sum)
class(vec)
## [1] "numeric"
좀 더 예를 들어보죠,
#iris 데이터의 각 데이터 타입을 보고 싶다면?
sapply(iris, class)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## "numeric" "numeric" "numeric" "numeric" "factor"
#3보다 큰 값만 추출하고 싶으면
y <- sapply(iris[, 1:4], function(x){ x > 3 })
Quiz
- iris 데이터를 0~1 사이 값으로 바꿔라
hint: 서로 다른 변수의 데이터가 scale이 다를 경우(어떤 변수는 -10~0 사이인데, 다른 변수는 10~1000인 경우), 정규분포를 활용한 정규화 뿐만 아니라, min, max를 활용하여 0~1사이로 바꾸는 방법도 있습니다. 즉, 다음 함수를 각 row에 적용하면 됩니다. \(\frac{x-min(x)}{max(x)-min(x)}\)
## Sepal.Length Sepal.Width Petal.Length Petal.Width
## [1,] 0.22222222 0.6250000 0.06779661 0.04166667
## [2,] 0.16666667 0.4166667 0.06779661 0.04166667
## [3,] 0.11111111 0.5000000 0.05084746 0.04166667
## [4,] 0.08333333 0.4583333 0.08474576 0.04166667
## [5,] 0.19444444 0.6666667 0.06779661 0.04166667
## [6,] 0.30555556 0.7916667 0.11864407 0.12500000
apply의 사촌들
이제부터는 apply와 비슷한 원리지만, 각 상황에 맞게 tapply, mapply 가 있는데, 자주 사용되지는 않지만, 한 번 보고 갈게요.
#tapply : 각 집단에 따라 데이터를 처리하고 싶을때
str(iris)
## 'data.frame': 150 obs. of 5 variables:
## $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
## $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
## $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
## $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
## $ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
#예를 들어, iris 데이터에서 각 종별로 Sepal.Length의 평균을 알고 싶으면?
#tapply(데이터, 색인, 함수) #여기서 색인은 factor!
tapply(iris$Sepal.Length, iris$Species, mean)
## setosa versicolor virginica
## 5.006 5.936 6.588
Quiz
- Species 별 Sepal.Width 의 분산은?
## setosa versicolor virginica
## 0.14368980 0.09846939 0.10400408
mapply
여러 벡터에 동일한 함수를 적용하고 싶을때 사용합니다. 아래와 같이 최대공약수를 구하는 함수 gcd가 있다고 합시다.
gcd <- function(a,b) {
if (b==0) return(a)
else return(gcd(b, a%%b))
}
gcd(6,4)
## [1] 2
#그러나, 아래와 같이 두 벡터의 각 원소간 값을 input으로 하고 싶을때 아래와 같은 문법은 오류가 발생합니다.
gcd(c(3,6,9), c(12,15,18))
## Warning in if (b == 0) return(a) else return(gcd(b, a%%b)): length > 1 이라
## 는 조건이 있고, 첫번째 요소만이 사용될 것입니다
## Warning in if (b == 0) return(a) else return(gcd(b, a%%b)): length > 1 이라
## 는 조건이 있고, 첫번째 요소만이 사용될 것입니다
## Warning in if (b == 0) return(a) else return(gcd(b, a%%b)): length > 1 이라
## 는 조건이 있고, 첫번째 요소만이 사용될 것입니다
## [1] 3 6 9
#이 경우 mapply 활용
mapply(gcd, c(3,6,9), c(12,15,18))
## [1] 3 3 9
참고 : Sampling
기계학습 모델링을 사용하다 보면, 무작위로 데이터를 추출해야할 경우가 생깁니다. 이럴 때 sample 함수를 사용하죠.
#1~10에서 무작위로 5개 추출
sample(1:10, 5) #중복 허락 하지 않고.
## [1] 4 8 9 5 7
sample(1:10, 5, replace=T) #중복을 허락해서 추출
## [1] 4 5 9 7 10
- iris 데이터에서 임의로 전체의 15% 데이터 추출하기
index <- 1:nrow(iris) # 1부터 iris행의 개수
train_idx <- sample(index, round(nrow(iris)*0.15))
head(iris[train_idx,])
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 99 5.1 2.5 3.0 1.1 versicolor
## 56 5.7 2.8 4.5 1.3 versicolor
## 43 4.4 3.2 1.3 0.2 setosa
## 44 5.0 3.5 1.6 0.6 setosa
## 135 6.1 2.6 5.6 1.4 virginica
## 139 6.0 3.0 4.8 1.8 virginica
'강의 및 세미나 자료 > R' 카테고리의 다른 글
R로 크롤링하기 - 보배드림 예제 (20) | 2016.08.07 |
---|---|
R 핵심만 배우기 #5 - dplyr (1) | 2016.08.04 |
R 핵심만 배우기 #3 - 데이터 프레임(data.frame) 첫번째 (1) | 2016.08.01 |
R 핵심만 배우기 #2 - 리스트, 메트릭스, 배열 (0) | 2016.08.01 |
R 핵심만 배우기 #1 - 스칼라, 요인, 벡터 (2) | 2016.08.01 |
소중한 공감 감사합니다