4.9 mutate() 함수를 이용한 새로운 컬럼 생성

4.9.1 mutate() 함수의 기본 형식

함수 mutate()는 컬럼을 추가할 때 사용한다. 비슷한 기능을 하는 함수로 base 패키지의 transform()이 있지만, 함수 mutate()는 함수에서 새로 만든 열을 같은 함수 안에서 바로 사용할 수 있는 장점이 있다. 단, 새로 생성된 칼럼은 별도의 변수로 지정하거나 기존의 데이터에 덮어씌우지 않는 한 저장되지 않는다.

mutate(dataframe, new_var = expression_of_old_var, ..., .keep, .before, .after)

  • dataframe : 데이터 세트
  • new_var = expression_of_old_var : 새로운 컬럼(new_var)을 생성하는 식
  • : 여러 개 반복 가능
  • .keep : (“all,” “used,” “unused,” “none”)
  • .before
  • .after : 기존 변수 + 신규 변수 모두 keep**

4.9.2 새로운 컬럼 생성 예

x, y의 2개의 컬럼에 각각의 값을12로 하는 데이터 df 에 대해 x+y를 값으로 하는 새로운 컬럼 z를 생성해 보자.

# z = x + y 컬럼 생성
df <- tibble(x = 1, y = 2)
df
## # A tibble: 1 x 2
##       x     y
##   <dbl> <dbl>
## 1     1     2
mutate(df, z=x+y)
## # A tibble: 1 x 3
##       x     y     z
##   <dbl> <dbl> <dbl>
## 1     1     2     3
# 또는
df %>% mutate(z = x + y)
## # A tibble: 1 x 3
##       x     y     z
##   <dbl> <dbl> <dbl>
## 1     1     2     3

Cars93 데이터프레임에서 최소가격(Min.Price)과 최대가격(Max.Price)의 범위(Price_range)를 구해보자.

# mutate(dataframe, new_var = operation of old vars, ...) : Create(add) new columns 
Cars93_1 <- Cars93[c(1:10),                             # subset for better printing  : (10 X 3)
                   c("Model", "Min.Price", "Max.Price")]      
Cars93_1 <- mutate(Cars93_1, 
                   Price_range = Max.Price - Min.Price) 
Cars93_1
##         Model Min.Price Max.Price Price_range
## 1     Integra      12.9      18.8         5.9
## 2      Legend      29.2      38.7         9.5
## 3          90      25.9      32.3         6.4
## 4         100      30.8      44.6        13.8
## 5        535i      23.7      36.2        12.5
## 6     Century      14.2      17.3         3.1
## 7     LeSabre      19.9      21.7         1.8
## 8  Roadmaster      22.6      24.9         2.3
## 9     Riviera      26.3      26.3         0.0
## 10    DeVille      33.0      36.3         3.3
# 또는
Cars93_1   %>%   mutate(Price_range = Max.Price - Min.Price) 
##         Model Min.Price Max.Price Price_range
## 1     Integra      12.9      18.8         5.9
## 2      Legend      29.2      38.7         9.5
## 3          90      25.9      32.3         6.4
## 4         100      30.8      44.6        13.8
## 5        535i      23.7      36.2        12.5
## 6     Century      14.2      17.3         3.1
## 7     LeSabre      19.9      21.7         1.8
## 8  Roadmaster      22.6      24.9         2.3
## 9     Riviera      26.3      26.3         0.0
## 10    DeVille      33.0      36.3         3.3
Cars93_1
##         Model Min.Price Max.Price Price_range
## 1     Integra      12.9      18.8         5.9
## 2      Legend      29.2      38.7         9.5
## 3          90      25.9      32.3         6.4
## 4         100      30.8      44.6        13.8
## 5        535i      23.7      36.2        12.5
## 6     Century      14.2      17.3         3.1
## 7     LeSabre      19.9      21.7         1.8
## 8  Roadmaster      22.6      24.9         2.3
## 9     Riviera      26.3      26.3         0.0
## 10    DeVille      33.0      36.3         3.3

Cars93 데이터프레임에서 최소가격(Min.Price)과 최대가격(Max.Price)의 범위(Price_range)와 최소가격 대비 최대가격의 비율(Price_ration = Max.Price/Min.Price) 을 나타내는 새로운 컬럼을 생성해 보자.

# mutate(dataframe, new_var = operation of old vars, ...) : Create(add) new columns 
Cars93_1 <- mutate(Cars93_1, 
                   Price_range = Max.Price - Min.Price, 
                   Price_ratio = Max.Price / Min.Price) 
Cars93_1
##         Model Min.Price Max.Price Price_range Price_ratio
## 1     Integra      12.9      18.8         5.9    1.457364
## 2      Legend      29.2      38.7         9.5    1.325342
## 3          90      25.9      32.3         6.4    1.247104
## 4         100      30.8      44.6        13.8    1.448052
## 5        535i      23.7      36.2        12.5    1.527426
## 6     Century      14.2      17.3         3.1    1.218310
## 7     LeSabre      19.9      21.7         1.8    1.090452
## 8  Roadmaster      22.6      24.9         2.3    1.101770
## 9     Riviera      26.3      26.3         0.0    1.000000
## 10    DeVille      33.0      36.3         3.3    1.100000

4.9.3 새로운 만든 컬럼(변수)를 이용하여 또 다른 컬럼 생성하기

mutate() 함수는 하나의 함수 명령문 안에서 새로 만든 변수를 바로 이용하여, 또 다른 변수의 input 변수로 사용할 수 있다.

예를 들어, 앞의 예에서 생성한 Price_range 변수의 값이 5이상이면 1, 아니면 0을 값으로 하는 Price_range_cd 컬럼을 생성고 그 결과를 Cars93_2 테이블에 저장해 보자. ( Price_range_cd = ifelse(Price_range >= 5, 1, 0))

# comparison with {dplyr} mutate() and {base} transform() 
Cars93_2 <- mutate(Cars93_1, 
                   Price_range = Max.Price - Min.Price, 
                   Price_range_cd = ifelse(Price_range >= 5, 1, 0))
Cars93_2
##         Model Min.Price Max.Price Price_range Price_ratio Price_range_cd
## 1     Integra      12.9      18.8         5.9    1.457364              1
## 2      Legend      29.2      38.7         9.5    1.325342              1
## 3          90      25.9      32.3         6.4    1.247104              1
## 4         100      30.8      44.6        13.8    1.448052              1
## 5        535i      23.7      36.2        12.5    1.527426              1
## 6     Century      14.2      17.3         3.1    1.218310              0
## 7     LeSabre      19.9      21.7         1.8    1.090452              0
## 8  Roadmaster      22.6      24.9         2.3    1.101770              0
## 9     Riviera      26.3      26.3         0.0    1.000000              0
## 10    DeVille      33.0      36.3         3.3    1.100000              0
# 또는
Cars93_2 <- Cars93_1 %>% 
                mutate( Price_range = Max.Price - Min.Price, 
                        Price_range_cd = ifelse(Price_range >= 5, 1, 0))
Cars93_2
##         Model Min.Price Max.Price Price_range Price_ratio Price_range_cd
## 1     Integra      12.9      18.8         5.9    1.457364              1
## 2      Legend      29.2      38.7         9.5    1.325342              1
## 3          90      25.9      32.3         6.4    1.247104              1
## 4         100      30.8      44.6        13.8    1.448052              1
## 5        535i      23.7      36.2        12.5    1.527426              1
## 6     Century      14.2      17.3         3.1    1.218310              0
## 7     LeSabre      19.9      21.7         1.8    1.090452              0
## 8  Roadmaster      22.6      24.9         2.3    1.101770              0
## 9     Riviera      26.3      26.3         0.0    1.000000              0
## 10    DeVille      33.0      36.3         3.3    1.100000              0

base 패키지의 transform() 함수도 하나의 명령문 안에 새로 만든 변수를 다른 신규 변수의 input 변수로 사용할 수 있다.

# {base} transform()
Cars93_3 <- transform(Cars93_1, 
                      Price_range = Max.Price - Min.Price, 
                      Price_range_cd = ifelse(Price_range >= 5, 1, 0))
Cars93_3
##         Model Min.Price Max.Price Price_range Price_ratio Price_range_cd
## 1     Integra      12.9      18.8         5.9    1.457364              1
## 2      Legend      29.2      38.7         9.5    1.325342              1
## 3          90      25.9      32.3         6.4    1.247104              1
## 4         100      30.8      44.6        13.8    1.448052              1
## 5        535i      23.7      36.2        12.5    1.527426              1
## 6     Century      14.2      17.3         3.1    1.218310              0
## 7     LeSabre      19.9      21.7         1.8    1.090452              0
## 8  Roadmaster      22.6      24.9         2.3    1.101770              0
## 9     Riviera      26.3      26.3         0.0    1.000000              0
## 10    DeVille      33.0      36.3         3.3    1.100000              0

4.9.4 컬럼의 값을 새로운 값으로 변경하기

Cars93_1에 있는 Min.Price의 값을 1.2배를 하고, Max.Price값들은 1.3배로 변경해 보자. 그리고, 최소가격(Min.Price)과 최대가격(Max.Price)의 범위(Price_range)와 최소가격 대비 최대가격의 비율(Price_ration = Max.Price/Min.Price) 도 변경해 보자. 그 결과는 Cars93_4에 저장한다.)

Cars93_4 <- mutate(Cars93_1, 
                   Min.Price = Min.Price * 1.2,
                   Max.Price = Max.Price * 1.3,
                   Price_range = Max.Price - Min.Price,
                   Price_ratio = Max.Price / Min.Price)
Cars93_4
##         Model Min.Price Max.Price Price_range Price_ratio
## 1     Integra     15.48     24.44        8.96    1.578811
## 2      Legend     35.04     50.31       15.27    1.435788
## 3          90     31.08     41.99       10.91    1.351030
## 4         100     36.96     57.98       21.02    1.568723
## 5        535i     28.44     47.06       18.62    1.654712
## 6     Century     17.04     22.49        5.45    1.319836
## 7     LeSabre     23.88     28.21        4.33    1.181323
## 8  Roadmaster     27.12     32.37        5.25    1.193584
## 9     Riviera     31.56     34.19        2.63    1.083333
## 10    DeVille     39.60     47.19        7.59    1.191667
  • 현재의 컬럼의 값을 새로운 값으로도 쉽게 변경할 수 있음을 알 수 있다.

4.9.5 .keep 인수의 사용 예

mutate() 함수의 인수로 .keep= 인수를 사용할 수 있다. 디폴트 값은 “all”이다. 다음의 예를 실행해 보면 쉽게 이해할 수 있다. .keep 이 가질 수 있는 옵션은 all(default), used, unused, none 등이 있다.

# Experimental: You can override with `.keep`
df <- tibble(x = 1, y = 2, a = "a", b = "b")
df %>% mutate(z = x + y, .keep = "all") # the default
## # A tibble: 1 x 5
##       x     y a     b         z
##   <dbl> <dbl> <chr> <chr> <dbl>
## 1     1     2 a     b         3
df %>% mutate(z = x + y, .keep = "used")
## # A tibble: 1 x 3
##       x     y     z
##   <dbl> <dbl> <dbl>
## 1     1     2     3
df %>% mutate(z = x + y, .keep = "unused")
## # A tibble: 1 x 3
##   a     b         z
##   <chr> <chr> <dbl>
## 1 a     b         3
df %>% mutate(z = x + y, .keep = "none") # same as transmute()
## # A tibble: 1 x 1
##       z
##   <dbl>
## 1     3
  • .keep = all : df의 컬럼 변수 전체(x, y, a, b)와 새로 생성된 변수(z) 모두를 보여준다. (default)

  • .keep = used : df의 컬럼 변수 중 새 변수를 만드는데 사용된 변수(xy)와 새 변수(z)를 보여준다.

  • .keep = unused : df의 컬럼 변수 중 새 변수를 만드는데 사용되지 않은 변수(a와 b)와 새 변수(z)를 보여준다.

  • .keep = none : 새 변수(z) 만을 보여준다.

4.9.6 .after.before 인수의 사용 예

mutate() 함수의 .after.before 인수를 이용하여 새로 생성된 변수의 위치를 지정할 수 있다.

# Experimental: you can override with `.before` or `.after`
df <- tibble(x = 1, y = 2)
df %>% mutate(z = x + y)
## # A tibble: 1 x 3
##       x     y     z
##   <dbl> <dbl> <dbl>
## 1     1     2     3
df %>% mutate(z = x + y, .before = 1)     # z를 1번째 컬럼의 왼 쪽에 표시
## # A tibble: 1 x 3
##       z     x     y
##   <dbl> <dbl> <dbl>
## 1     3     1     2
df %>% mutate(z = x + y, .after = x)      # z를 x 컬럼 오른 쪽에 표지
## # A tibble: 1 x 3
##       x     z     y
##   <dbl> <dbl> <dbl>
## 1     1     3     2

4.9.7 transmute() 함수를 이용한 새로운 컬럼 생성

mutate() 함수가 기존 변수와 신규 변수를 모두 관리하는 것과 달리, transmute() 함수는 신규 변수만 저장을 하고 기존 변수들은 모두 없앤다.

4.9.7.1 transmute() 함수의 기본 형식

transmute(dataframe, 새로운 변수 = 기존 변수 조합한 수식, ...)

  • dataframe : 데이터 세트
  • transmute()의 인수와 같음…

Cars93_1의 데이터 세트에서 최소가격(Min.Price)과 최대가격(`Max.Price)의 차이를 나타내는 범위(Price_range) 변수와 최소가격 대비 최대가격의 비율(Price_ration = Max.Price/Min.Price) 의 새로운 변수를 생성한 후에, 이들 2개의 신규변수만 Cars93_5에 저장해 보자.

# transmute() : Create(add) new columns 
Cars93_1 <- Cars93[c(1:10), c("Model", "Min.Price", "Max.Price")]      # subset for better printing 
Cars93_1
##         Model Min.Price Max.Price
## 1     Integra      12.9      18.8
## 2      Legend      29.2      38.7
## 3          90      25.9      32.3
## 4         100      30.8      44.6
## 5        535i      23.7      36.2
## 6     Century      14.2      17.3
## 7     LeSabre      19.9      21.7
## 8  Roadmaster      22.6      24.9
## 9     Riviera      26.3      26.3
## 10    DeVille      33.0      36.3
Cars93_5 <- transmute(Cars93_1, 
                      Price_range = Max.Price - Min.Price, 
                      Price_Min_Max_ratio = Max.Price / Min.Price) 
Cars93_5
##    Price_range Price_Min_Max_ratio
## 1          5.9            1.457364
## 2          9.5            1.325342
## 3          6.4            1.247104
## 4         13.8            1.448052
## 5         12.5            1.527426
## 6          3.1            1.218310
## 7          1.8            1.090452
## 8          2.3            1.101770
## 9          0.0            1.000000
## 10         3.3            1.100000

이는 mutate() 함수에서 .keep 인수의 값을 “none”으로 한 결과와 같음을 알 수 있다.

# mutate( , .keep = "none") == transmute() : Create(add) new columns 
Cars93_1 <- Cars93[c(1:10), c("Model", "Min.Price", "Max.Price")]      # subset for better printing 
Cars93_1
##         Model Min.Price Max.Price
## 1     Integra      12.9      18.8
## 2      Legend      29.2      38.7
## 3          90      25.9      32.3
## 4         100      30.8      44.6
## 5        535i      23.7      36.2
## 6     Century      14.2      17.3
## 7     LeSabre      19.9      21.7
## 8  Roadmaster      22.6      24.9
## 9     Riviera      26.3      26.3
## 10    DeVille      33.0      36.3
Cars93_6 <- mutate(Cars93_1, 
                      Price_range = Max.Price - Min.Price, 
                      Price_Min_Max_ratio = Max.Price / Min.Price,
                   .keep = "none") 
Cars93_6
##    Price_range Price_Min_Max_ratio
## 1          5.9            1.457364
## 2          9.5            1.325342
## 3          6.4            1.247104
## 4         13.8            1.448052
## 5         12.5            1.527426
## 6          3.1            1.218310
## 7          1.8            1.090452
## 8          2.3            1.101770
## 9          0.0            1.000000
## 10         3.3            1.100000