(12주차) 11월30일 + 11월25일보충강의
select, filter, mutate, group_by, summarise
-
(1/7) 숙제풀이
-
(2/7) select
-
(3/7) filter
-
(4/7) mutate
-
(5/7) group_by, summarise
-
(6/7) flight data
-
(7/7) 숙제설명
library(tidyverse)
-
길이가 50인 벡터생성
A = rnorm(10*5)
A ## 길이가 50인 벡터에 정규분포에 추출한 값
-
매트릭스로 변경
dim(A) = c(10,5)
A
-
티블로 변경 (자동으로 V1,...,V5 열의 이름이 지정됨)
A = as_tibble(A)
A
-
컬럼의 이름 확인
colnames(A)
-
칼럼의 이름을 바꾸고 싶다면?
colnames(A) = c('X1','X2','X3','X4','X5')
A
-
처음 3개의 칼럼과 마지막 1개의 칼럼을 선택하고 싶다면?
A %>% select(1:3,5)
-
열의 이름을 통하여서도 선택할 수 있음
A %>% select(X1:X3,X5)
-
열의 이름과 위치인덱스를 혼합하여 사용할 수 있음
A %>% select(X1:X3, 5)
-
열의 이름과 위치인덱스를 혼합하여 사용할 수 있음 (2)
A %>% select(1:3, X5)
-
선택한 결과를 다른 변수에 저장가능
A %>% select(1:3, X5) -> B
B
-
A라는 자료를 다시 살펴보자.
A
-
특정열을 제외하고 선택
A %>% select(-(X1:X3))
A %>% select(-(1:3))
-
데이터 확인
A
-
열의 이름 확인 및 변경
colnames(A)
colnames(A)= c('XY1','XY2','XZ1','XZ2','X5')
A
-
XY로 시작하는 열을 선택
A %>% select(starts_with('XY'))
-
데이터확인
A
-
2로 끝나는 열을 선택
A %>% select(ends_with('2'))
-
데이터확인
A
-
Z를 포함하는 열을 선택
A %>% select(contains("Z"))
-
데이터확인
A
-
Z를 포함하는 열을 앞으로 이동시킴
A %>% select(contains("Z"),everything())
-
데이터확인
A
-
X5>0인 행들만 뽑고싶다.
A %>% filter(X5>0)
-
X5>0 이고 XY2>0 인 행들만 뽑고싶다.
A %>% filter(X5>0 & XY2>0)
-
위의 결과에서 XZ를 포함하는 열을 뽑고싶다.
A %>% filter(X5>0 & XY2>0) %>% select(contains("XZ"))
-
데이터를 확인
A
-
새로운 변수추가
A %>% mutate(X6=abs(X5))
-
여러개의 새로운 변수를 추가하는 기능도 있음
A %>% mutate(X6=abs(X5),Z7=X5**2)
-
표준화
A %>% mutate(X6=abs(X5),Z7=X5**2,Z8=(Z7-mean(Z7))/sd(Z7))
sex = c("M","M","M","F","F","F","F")
value = c(1,2,3,10,20,30,40)
df = tibble(sex,value)
df
df %>% group_by(sex) %>% summarise(mean_value=mean(value))
- 그룹별로 묶은 다음에 평균을 계산함
-
신기한데? 다른것도 실습해보자.
df %>% group_by(sex) %>% summarise(sqrt_value=sqrt(value))
- 의도한 결과는 아님. 이렇게 쓰는건 아니에요!
-
아래를 수행한 꼴임
df %>% mutate(sqrt_value=sqrt(value))
-
summarise
에 쓸수 있는 함수꼴은 평균과 같이 $n$개의 벡터가 입력으로 올때 하나의 스칼라출력을 주는 함수모양이어야함
-
예를들면 아래는 가능
df %>% group_by(sex) %>% summarise(mean_sqrt_value=mean(sqrt(value)))
(sqrt(1)+sqrt(2)+sqrt(3))/3
(sqrt(10)+sqrt(20)+sqrt(30)+sqrt(40))/4
-
group_by + mutate
df %>% group_by(sex) %>% mutate(value2= value-mean(value))
-
위의 코드는 아래와 동일하다.
df %>% filter(sex=='M') %>% mutate(value2 = value - mean(value))
df %>% filter(sex=='F') %>% mutate(value2 = value - mean(value))
df %>% filter(sex=='M') %>% mutate(value2 = value - mean(value)) -> A1
df %>% filter(sex=='F') %>% mutate(value2 = value - mean(value)) -> A2
A1
A2
-
두 데이터프레임을 합치면 된다. (어떻게..??)
rbind(A1,A2) # 아 몰라.. 매트릭스처럼 하면 되지 않을까?
- 된다... (떡밥)
-
NA 포함되어도 개별연산은 괜찮아요
x = c(1,2,NA,4,5)
x
x+1
x**2
-
그런데 summarise에 쓸 연산은 망가져요
mean(x)
max(x)
-
수정을 위해서
mean(x,na.rm=TRUE)
max(x,na.rm=TRUE)
-
데이터프레임에서도 비슷합니다.
tibble(x) %>% mutate(z=x+1)
tibble(x) %>% summarise(z=mean(x))
tibble(x) %>% summarise(z=mean(x,na.rm=TRUE))
-
NA를 무조건 없애는것이 좋은가?
x<- c(1,2,NA,4)
y<- c(1,NA,3,4)
z<- c(NA,2,3,4)
w<- c(1,2,3,NA)
tibble(x,y,z,w)
tibble(x,y,z,w) %>% mutate(xy=x+y)
tibble(x,y,z,w) %>% mutate(xy=x+y) %>% summarise(mean_xy = mean(xy,na.rm=TRUE))
- 그래도 NA를 살려두면 좋지않을까? 데이터 하나하나가 소중하니까요!
-
결측치를 살릴까 죽일까?
x=c(1,2,3,4,NA,5,6,7)
y=c(-1,-2,-3,-4,77,-5,-6,-7)
tibble(x,y)
tibble(x,y) %>% filter(x>3,x<7)
- ?? y=77 은 죄없이 사라짐. 사실 보류로 봐야하지않나? NA는 3보다 크지 않지만 작지도 않음, 또한 7보다 크지 않지만 작지도 않음
-
결측치를 살리고 싶다.
tibble(x,y) %>% filter(is.na(x))
tibble(x,y) %>% filter(is.na(x) | (x>3 & x<7))
- 데이터는 소중함
library(nycflights13)
df=flights
df
-
1월1일의 모든 항공편을 선택하고싶다.
df %>% filter(month==1 & day==1)
df %>% filter(month==1 , day==1)
-
11월에 출발하거나 12월에 출발한 항공
df %>% filter(month==11 | month==12)
-
아래와 동일한 코드
df %>% filter(month %in% c(11,12))
-
arr_delay <=120 이고 dep_delay <=120 인 항공편을 찾고 싶다.
df %>% filter(arr_delay <= 120, dep_delay<=120)
df %>% filter(arr_delay <= 120 & dep_delay<=120)
df %>% filter(!(arr_delay > 120 | dep_delay> 120))
-
변수이름을 확인하자.
df %>% colnames
df %>% names
- 왜 방법이 두개있을까? (떡밥)
-
변수가 너무 많아서 귀찮음. 몇개만 추리자.
- year~day 는 포함
- delay로 끝나는 변수들
- distance, air_time
df %>% select(year:day, ends_with('delay'), distance, air_time)
-
아래의 수식을 이용해서 gain, speed를 계산하자.
- gain = dep_delay - arr_delay
- speed = distance / air_time
df %>%
select(year:day, ends_with('delay'), distance, air_time) %>%
mutate(gain = dep_delay - arr_delay, speed = distance / air_time)
-
year, month, day 로 그룹핑을하고 평균속도와 평균gain을 계산해보자.
df %>%
select(year:day, ends_with('delay'), distance, air_time) %>%
mutate(gain = dep_delay - arr_delay, speed = distance / air_time) %>%
group_by(year,month,day) %>%
summarise(gain_mean=mean(gain),speed_mean=mean(speed))
- 다 NA가 나옴..
df %>%
select(year:day, ends_with('delay'), distance, air_time) %>%
mutate(gain = dep_delay - arr_delay, speed = distance / air_time) %>%
group_by(year,month,day) %>%
summarise(gain_mean=mean(gain,na.rm=TRUE),speed_mean=mean(speed,na.rm=TRUE))
강화유리와 유리를 구분할 수 있는 유리 장인이 있다.
이 유리장인은 80퍼센트의 확률로 강화유리를 고른다.
총 10명의 참가자가 있고 이 참가자들은 (유리,강화유리)의 조합으로 이루어진 징검다리를 5번연속으로 건너야 한다.
아래의 경우에 참가자들은 평균적으로 몇명이 살아남겠는가?
(1) 일반인1 - 일반인2 - .... - 일반인9 - 유리장인 || (강화유리, 유리)
(2) 유리장인 - 일반인1 - 일반인2 - ... - 일반인9 || (강화유리, 유리)
1000번 시뮬레이션을 하여 결과를 추정하라.
(단, 일반인은 50%의 확률로 강화유리를 고를수 있다고 하자)
[예시] (1)의 시뮬레이션 결과가 아래와 같다고 하자.
- 첫번째 징검다리: 유리장인이 강화유리 선택
- 두번째 징검다리: 유리장인이 강화유리 선택
- 세번째 징검다리: 유리장인이 일반유리 선택 $\to$ 유리장인 탈락 & 일반인9는 당연히 강화유리를 선택
- 네번째 징검다리: 일반인9가 일반유리 선택 $\to$ 일반인9 탈락 & 일반인8은 당연히 강화유리 선택
- 다섯번째 징검다리: 일반인8이 강화유리 선택
이 경우는 일반인8,일반인7, $\dots$, 일반인1이 살아남으므로 8명이 살아남는다.
[예시] (2)의 시뮬레이션 결과가 아래와 같다고 하자.
- 첫번째 징검다리: 일반인9 일반유리 선택 $\to$ 일반인9 탈락 & 일반인8은 강화유리 선택
- 두번째 징검다리: 일반인8 일반유리 선택 $\to$ 일반인8 탈락 & 일반인7은 강화유리 선택
- 세번째 징검다리: 일반인7 일반유리 선택 $\to$ 일반인7 탈락 & 일반인6은 강화유리 선택
- 네번째 징검다리: 일반인6 일반유리 선택 $\to$ 일반인6 탈락 & 일반인5는 강화유리 선택
- 다섯번째 징검다리: 일반인5 일반유리 선택 $\to$ 일반인5 탈락 & 일반인4는 강화유리 선택
이 경우는 일반인4,일반인3,일반인2,일반인1,유리장인 이 살아남는다. (따라서 5명)
-
즉 살아남을수 있는 최대인원수는 10명이며 최소인원수는 5명이다.
-
유리장인이 100%의 확률로 강화유리를 구분한다면 (1)의 경우 항상 10명이 살아남는다. (즉 평균도 10명)