티스토리 뷰

반응형

숫자와 문자가 섞여있을때, 문자만 분리하고 싶다면, 아래와 같이 하면된다. 경고메시지가 나오긴 하지만 무시해도 된다.

a = c(10,10,10, 'a', 'b', 'c', 20, 30, 'd')
# [1] "10" "10" "10" "a"  "b"  "c"  "20" "30" "d"

as.numeric(a)
# [1] 10 10 10 NA NA NA 20 30 NA

is.na(as.numeric(a))
# [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE

a[is.na(as.numeric(a))]
# [1] "a" "b" "c" "d"
# Warning message:
# NAs introduced by coercion

 

데이터 프레임으로 하는 경우도 비슷하다.

df = data.frame(keyword = c(10,10,10, 'a', 'b', 'c', 20, 30, 'd'))
df

# 출력결과
  keyword
1      10
2      10
3      10
4       a
5       b
6       c
7      20
8      30
9       d

# 숫자형으로 변환한 결과를 num 필드로 추가한다.
df$num = as.numeric(df$keyword)

# 추가결과
  keyword num
1      10  10
2      10  10
3      10  10
4       a  NA
5       b  NA
6       c  NA
7      20  20
8      30  30
9       d  NA

 

여기서 숫자를 제거하려면 is.na 의 결과를 활용해서 필터를 걸면 된다. 

is.na(df$num)
# [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE


df[is.na(df$num),]
# 숫자를 제거한 문자만 남은 결과
  keyword num
4       a  NA
5       b  NA
6       c  NA
9       d  NA

 

정규식으로 분리

warning 도 나오다보니, 이런 강제 형변환 방식보다는 정규식을 잘안다면 정규식으로 분리하는게 좋다. grep 함수는 입력된 정규식에 충족하는 데이터이면 인덱스를 리턴한다. value = TRUE 로 셋팅하면, 인덱스가 리턴되는게 아니라 해당 인덱스의 value 값이 리턴된다. df 데이터프레임에서는 인덱스를 넣어서 필터를 걸면 된다.

grep("\\d+", df$keyword)
# [1] 1 2 3 7 8

grep("\\d+", df$keyword, value = T)
# [1] "10" "10" "10" "20" "30"

df[grep("\\d+", df$keyword), ]
# [1] "10" "10" "10" "20" "30"

 

grepl 은 grep 과 거의 비슷한데 logical 벡터를 리턴한다. 이것도 데이터프레임에 인자로 넣으면 필터효과를 가지게 된다.

grepl("\\d+", df$keyword)
# [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE

df[grepl("\\d+", df$keyword), ]
# [1] "10" "10" "10" "20" "30"

 

tidyverse 로도 가능하다. warning 은 무시.

enframe(c(0,10,10, 'a', 'b', 'c', 20, 30, 'd'), name = NULL) %>% 
  mutate(num = as.numeric(value)) %>% 
  filter(is.na(num))
  
# 출력결과
# A tibble: 4 × 2
  value   num
  <chr> <dbl>
1 a        NA
2 b        NA
3 c        NA
4 d        NA
Warning message:
Problem with `mutate()` column `num`.
ℹ `num = as.numeric(value)`.
ℹ NAs introduced by coercion


enframe(c(0,10,10, 'a', 'b', 'c', 20, 30, 'd'), name = NULL) %>% 
  mutate(num = grepl("\\d+", value)) %>% 
  filter(num == T)
  
# 출력결과
# A tibble: 5 × 2
  value num  
  <chr> <lgl>
1 0     TRUE 
2 10    TRUE 
3 10    TRUE 
4 20    TRUE 
5 30    TRUE
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함