https://pastryofjsmath.tistory.com/27
파이썬 범주화,결측치 처리기법
A = { 'subject' : ["미적분학","선형대수학","해석학","정수론","수리통계학","수학을 위한 프로그래밍"], '평점' : [3.8,4.5,4.1,3.2,4.7,5], '학점' : [3,3,3,2,2,2], } df=pd.DataFrame(A) #결측치 처리. #1.결측치 행을 제
pastryofjsmath.tistory.com
위의 수치형 데이터전처리의 R버전입니다.
아래 csv파일을 이용했습니다.
df <- read.csv('',fileEncoding = 'CP949')
library(magrittr)
library(dplyr)
df<-df[-1]
df[-1]은 행의 인덱스를 제거하기 위함입니다.
df %>% str()
summary(df)
데이터의 구조와 수치형이면 어떻게 분포되어있는지 확인해줍니다.
#총 NA개수
df %>% is.na() %>% sum()
>3
#각 col마다 결측치가 얼마나 있는지 확인
colSums(is.na(df))
> subject 평점 학점 선수과목 강사진 수강금액 수강인원 좌석수 강의시작시간
0 0 0 0 0 1 1 1 0
개강일 종강일
0 0
총 NA개수와 col마다 결측치가 얼마나 있는지 확인하는 방법입니다.
아래는 결측치를 아예 제거하는 방법입니다.
두가지 모두 사용가능합니다.
##NA를 제거한 컬을 모두 보고 싶을 때
#sol1)
na.omit(df)
#sol2)
df[complete.cases(df),]
만약 어디에서 결측치가 발생했는지 보고싶다면?
df[apply(df,MARGIN = 1,FUN = function(x) any(is.na(x))),]
좀 더 쉽게 쓸 수 있을 것같은데 막상 떠오르지가 않네요;; filter로는 특정 컬럼만 보통 추출하니까요.
만약 filter를 사용한다 해도 결과는 같습니다.
df %>% filter(apply(df,MARGIN = 1,FUN = function(x) any(is.na(x))))
apply계열 함수 중 apply를 사용해서 행으로 FUN을 이용한 계산을 해줍니다.
any(is.na(x))에서 any는 하나라도 있으면 True를 반환해줍니다.
그러니까 any(is.na(x))는 x라는 것에서 결측치가 적어도 하나라도 있다면 True를 반환하는 것이죠.
다음은 수치형 컬럼과 그 외의 컬럼으로 분리하는 과정입니다.
#수치형과 그 외로 분리하는 과정
num_col <-df %>% select_if(is.numeric) %>% colnames()
char_col <-df %>% select_if(function(col) is.character(col) || is.factor(col)) %>% colnames()
#?select_if
#select_if를 사용하긴 위해선 dplyr패키지가 필요합니다.
select_if 를 사용했습니다. char_col에서 함수를 걸어주는 이유는 주석처리한 ?select_if를 실행하시면,
함수자체로 사용해야 하기 때문이죠.
다음은 수치형 결측치 대체방법입니다. 하나의 컬럼씩 하는 방법은 간단합니다.
df$수강인원 %>% mean(,na.rm = T)
ifelse(is.na(df$수강인원),mean(df$수강인원,na.rm = T),df$수강인원)
na.rm=T를 해줌으로 인해 NA값은 제외해서 평균으로 나타냅니다. 이를 이용해 ifelse문을 사용해줍니다.
하지만 모든 컬럼에 대해서 해줄려면? 모든 컬럼마다 ifelse을 사용해야할까요?
apply계열 함수를 사용하면 쉽게 가능합니다.
#수치형 컬럼의 결측값을 평균으로 대체
apply(df[num_col],MARGIN = 2,FUN = function(x) ifelse(is.na(x), mean(x, na.rm = TRUE), x))
++20240609 추가사항
R에서도 파이썬의 str.contains()과 비슷한 기능이 있습니다.
library(stringr)
#강사진 브레젤의 '브레'만으로 추출해내보자.
df$강사진[str_detect(df$강사진,'브레')]
> df$강사진[str_detect(df$강사진,'브레')]
[1] "브레젤"
#또는 기본 함수 grep()을 이용
grep(pattern='브레',x=df$강사진)
#출력이 순서로 나오므로,
df$강사진[grep(pattern='브레',x=df$강사진)]
> grep(pattern = '브레',x = df$강사진)
[1] 6
> df$강사진[grep(pattern = '브레',x = df$강사진)]
[1] "브레젤"
추가적으로 선수과목을 분리하고 싶다면, 다음과 같이 사용하시면 됩니다.
#일정패턴으로 분리되어있음.
str_split(string = df$선수과목,pattern = '/')
>str_split(string = df$선수과목,pattern = '/')
[[1]]
[1] "없음"
[[2]]
[1] "미적분학"
[[3]]
[1] "선형대수학" "미적분학"
[[4]]
[1] "선형대수학" "미적분학"
[[5]]
[1] "선형대수학" "미적분학"
[[6]]
[1] "선형대수학" "미적분학" "수리통계학"
#이를 데이터 프레임으로 변환하면?
str_df <- str_split(string = df$선수과목,pattern = '/') %>% unlist() %>% table() %>% as.data.frame()
> str_df
. Freq
1 미적분학 5
2 선형대수학 4
3 수리통계학 1
4 없음 1
'데이터 전처리 > R' 카테고리의 다른 글
ggplot을 이용한 데이터 시각화 - geom_bar(),geom_histogram() (0) | 2024.06.17 |
---|---|
파이썬 split,replace,extract [R ver.] (1) | 2024.06.11 |
자주 쓰이는 apply계열 함수 사용법 in r (0) | 2024.06.04 |
gsub()함수 기본 사용법 in r (1) | 2024.06.04 |
날짜 데이터 전처리 [in R] -strptime,str_extract(),substr() (0) | 2024.05.15 |