티스토리 뷰

반응형

R 프로그램에서 벡터를 만드는 방법은 여러가지가 있다. 직접 입력하거나, seq/rep/sample 등의 벡터생성하는 함수들을 사용하거나, 빈값으로 length 만 정하는 등 여러가지이다. 실제 퍼포먼스는 어떨지는 좀 확인은 해봐야겠으나, loop 를 사용하는 것은 R 에서는 권장하진 않는다. 일반적인 프로그램언어라면 for/while 문은 어느정도의 기본 문법이다보니 사용을 많이 하게 되는데, R 에서는 대부분 벡터를 입력받아 벡터로 리턴하는 함수체계가 대부분이라 loop 를 거의 사용하지 않도록 코딩을 할 수 있다. 

특정 조건을 만족하는 숫자인 경우, 문자열로 치환하여 별도의 벡터형으로 저장해보자. 0~4는 C등급, 5~8은 B등급, 9~10은 A등급으로 변경하려면 어떻게 해야 할까. 일반적이라면 for 문으로 해보려 할 것이다.

set.seed(12322)
a = sample(1:10, 10)
a
# [1]  6  7  9  1  8  2  5  3  4 10

b = character(length(a))
# [1] "" "" "" "" "" "" "" "" "" ""

for(i in seq_along(a)){
  if(a[i] >= 9){
    b[i] = "A"
  }else if(a[i] >= 5){
    b[i] = "B"
  }else{
    b[i] = "C"
  }
}

b
# [1] "B" "B" "A" "C" "B" "C" "B" "C" "C" "A"

 

벡터를 길이에 따라 초기화 하는 함수는 여러개 있으니 참고.

character(10)
# [1] "" "" "" "" "" "" "" "" "" ""
numeric(10)
# [1] 0 0 0 0 0 0 0 0 0 0
integer(10)
# [1] 0 0 0 0 0 0 0 0 0 0
logical(10)
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

 

for 문 없이도 가능하다. which 함수를 우선 알아야 한다. 파라메터에 입력된 조건을 만족하는 인덱스 정보를 리턴한다. 아래에 보면 7이상인 숫자의 위치 2,3,5,10 을 리턴한다.

# a
# [1]  6  7  9  1  8  2  5  3  4 10

which(a >= 7)
# [1]  2  3  5 10

which(LETTERS == "R")
# [1] 18

 

loop 없이 만들수 있으며, 이게 10개 여서 속도차이가 안나겠지만, 대량의 데이터에서는 훨씬 더 빠른 연산속도가 나올 것이다. 

b = rep("C", length(a))
# [1] "C" "C" "C" "C" "C" "C" "C" "C" "C" "C"

b[a >= 5] = rep('B', length(which(a >= 5)))
# [1] "B" "B" "B" "C" "B" "C" "B" "C" "C" "B"

b[a >= 9] = rep('A', length(which(a >= 9)))
# 최종결과
# [1] "B" "B" "A" "C" "B" "C" "B" "C" "C" "A"

 

tidyverse 로 변환하는 걸 몇개 만들어 본다.

# 첫번째 방법
tibble(a) %>% 
  mutate(a0 = ifelse(a >= 0, "C", ""), 
         a5 = ifelse(a >= 5, "B", ""), 
         a9 = ifelse(a >= 9, "A", "")) %>% 
  mutate(result = str_sub(str_c(a9, a5, a0), 0, 1))

# 출력결과
 A tibble: 10 × 5
       a a0    a5    a9    result
   <int> <chr> <chr> <chr> <chr> 
 1     6 C     "B"   ""    B     
 2     7 C     "B"   ""    B     
 3     9 C     "B"   "A"   A     
 4     1 C     ""    ""    C     
 5     8 C     "B"   ""    B     
 6     2 C     ""    ""    C     
 7     5 C     "B"   ""    B     
 8     3 C     ""    ""    C     
 9     4 C     ""    ""    C     
10    10 C     "B"   "A"   A



# 두번째 방법
tibble(a) %>% 
  mutate(a1 = 'C') %>% 
  mutate(a1 = ifelse(a >= 5, 'B', a1)) %>% 
  mutate(a1 = ifelse(a >= 9, 'A', a1))
  
# 출력결과
# A tibble: 10 × 2
       a a1   
   <int> <chr>
 1     6 B    
 2     7 B    
 3     9 A    
 4     1 C    
 5     8 B    
 6     2 C    
 7     5 B    
 8     3 C    
 9     4 C    
10    10 A


# 세번째 방법 (join 이용)
b = tibble(x = c(1,2,3), y = c("C", "B", "A"))

tibble(a) %>% 
  mutate(a0 = ifelse(a >= 0, 1, 0), 
         a5 = ifelse(a >= 5, 1, 0), 
         a9 = ifelse(a >= 9, 1, 0)) %>% 
  mutate(a_sum = a0 + a5 + a9)  %>% 
  left_join(b, by = c("a_sum" = "x"))
  
# 출력결과 
# A tibble: 10 × 6
       a    a0    a5    a9 a_sum y    
   <int> <dbl> <dbl> <dbl> <dbl> <chr>
 1     6     1     1     0     2 B    
 2     7     1     1     0     2 B    
 3     9     1     1     1     3 A    
 4     1     1     0     0     1 C    
 5     8     1     1     0     2 B    
 6     2     1     0     0     1 C    
 7     5     1     1     0     2 B    
 8     3     1     0     0     1 C    
 9     4     1     0     0     1 C    
10    10     1     1     1     3 A
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함