4.3 데이터 프레임의 컬럼 선택: select()

4.3.1 select() 함수의 기본 형식

select(dataframe, VAR1, VAR2, ...)

  • dataframe : 데이터 세트
  • VAR1, VAR2 : 선택하고자 하는 컬럼 이름 기입

Cars93_1 데이터 세트로부터 제조사명(Manufacturer), 최대가격(Max.Price), 고속도로연비(MPG.highway) 3개 변수(칼럼)를 선택해 보자.

# select() : Select columns by name 
# select(Cars93_1, Manufacturer, Max.Price, MPG.highway)
# 또는
# Cars93_1 %>%
#         select(Manufacturer, Max.Price, MPG.highway)
  • 위의 스크립트를 실행하면 다음과 같은 에러메시지가 나온다.
Error in select(Cars93_1, Manufacturer, Max.Price, MPG.highway) : 
  사용되지 않은 인자 (Manufacturer, Max.Price, MPG.highway)
  • 이는 dplyr 패키지의 select() 함수와 MASS 패키지의 select() 함수가 충돌하기 때문이다.

이러한 패키지 간의 충돌을 방지하기 위한 해결 방법은 다음과 같다.

  • (방법 1) dplyr::select() : select() 함수에 명시적으로 dplyr패키지 명을 지정하는 방법
  a1 <- dplyr::select(Cars93_1, Manufacturer, Max.Price, MPG.highway)
  head(a1)
##   Manufacturer Max.Price MPG.highway
## 1        Acura      18.8          31
## 2        Acura      38.7          25
## 3         Audi      32.3          26
## 4         Audi      44.6          26
## 5          BMW      36.2          30
## 6        Buick      17.3          31
  • (방법 2) select <- dplyr::select : select() 함수가 dplyr 패키지의 select() 함수임을 명시적으로 지정
  select <- dplyr::select 
  a2 <- select(Cars93_1, Manufacturer, Max.Price, MPG.highway)
  head(a2)
##   Manufacturer Max.Price MPG.highway
## 1        Acura      18.8          31
## 2        Acura      38.7          25
## 3         Audi      32.3          26
## 4         Audi      44.6          26
## 5          BMW      36.2          30
## 6        Buick      17.3          31
  # 또는
  a3 <- Cars93_1 %>% 
    select(Manufacturer, Max.Price, MPG.highway)
  head(a3)
##   Manufacturer Max.Price MPG.highway
## 1        Acura      18.8          31
## 2        Acura      38.7          25
## 3         Audi      32.3          26
## 4         Audi      44.6          26
## 5          BMW      36.2          30
## 6        Buick      17.3          31
  • (방법 3) MASS 패키지를 먼저 로딩하고, 나중에 dplyr 패키지를 로딩하기
  library(MASS) 
  library(dplyr)                                              # dplyr loading after MASS
  a4 <- select(Cars93, Manufacturer, Max.Price, MPG.highway)
  head(a4)
##   Manufacturer Max.Price MPG.highway
## 1        Acura      18.8          31
## 2        Acura      38.7          25
## 3         Audi      32.3          26
## 4         Audi      44.6          26
## 5          BMW      36.2          30
## 6        Buick      17.3          31

이제 정상적으로 3개의 컬럼이 선택되어 출력이 된다.

4.3.2 a번째 부터 n번째의 연속적 컬럼 선택

select(dataframe, VAR_a:VAR_n, ...)

  • dataframe : 데이터 세트

  • VAR_a:VAR_n : a번째부터 n번째 변수

서로 인접한 연속된 변수들을 선택하고자 할 때는 예시처럼 :를 사용한다.

Cars93_1 데이터 세트에서 1번째에 위치한 제조사(Manufacturer) ~ 5번째에 위치한 가격(Price)까지 연속적으로 5개의 변수들을 선택해 보자. (컬럼의 이름으로)

a5 <- select(Cars93_1, Manufacturer:Price)
head(a5)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
# 또는
a6 <- Cars93_1 %>%
         select(Manufacturer:Price)
head(a6)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
  • 위의 결과로 Manufacturer, Model, Type, Min.Price, 그리고 Price 등의 5개의 컬럼이 선택된다.

아래와 같이 연속적인 컬럼의 위치를 알고 있으면 (가령 a부터 n번째 위치) a:n처럼 숫자를 직접 입력해주면 바로 위의 결과와 동일한 결과를 얻을 수 있다.

a7 <- select(Cars93_1, 1:5)
head(a7)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
# 또는
a8 <- Cars93_1 %>%
         select(1:5)
head(a8)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7

참고로, dplyr 패키지의 select() 함수는 base패키지에 내장되어 있는 subset(dataframe, select=...) 함수와 기능이 같다. 아래의 subset() 함수의 결과와 비교해 보면, 그 결과가 위와 같다.

a9 <- subset(Cars93_1, select = c(Manufacturer:Price))
head(a9)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
# 또는
a10 <- Cars93_1 %>%
         subset(select = c(Manufacturer:Price))
head(a10)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
a11 <- subset(Cars93_1, select = c(1:5))
head(a11)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7
# 또는
a12 <- Cars93_1 %>%
         subset(select = c(1:5))
head(a12)
##   Manufacturer   Model    Type Min.Price Price
## 1        Acura Integra   Small      12.9  15.9
## 2        Acura  Legend Midsize      29.2  33.9
## 3         Audi      90 Compact      25.9  29.1
## 4         Audi     100 Midsize      30.8  37.7
## 5          BMW    535i Midsize      23.7  30.0
## 6        Buick Century Midsize      14.2  15.7

4.3.3 a번째 부터 n번째의 연속적 컬럼을 제외한 선택

select(dataframe, -(VAR_a:VAR_n, …))

  • dataframe : 데이터 세트

  • VAR_a:VAR_n : a번째부터 n번째 변수

컬럼 이름 앞에 -’(minus) 부호를 사용하면, 그 컬럼은 제외하고 선택하게 된다.

# select(dataframe, -var1, -var2, ...) : to drop variables
a13 <- select(Cars93_1, -(Manufacturer:Price)); head(a13)
##   Max.Price MPG.city MPG.highway
## 1      18.8       25          31
## 2      38.7       18          25
## 3      32.3       20          26
## 4      44.6       19          26
## 5      36.2       22          30
## 6      17.3       22          31
# 또는
a14 <- select(Cars93_1, -(1:5)); head(a14)
##   Max.Price MPG.city MPG.highway
## 1      18.8       25          31
## 2      38.7       18          25
## 3      32.3       20          26
## 4      44.6       19          26
## 5      36.2       22          30
## 6      17.3       22          31
# 또는
a15 <- Cars93_1 %>%
         select(-(Manufacturer:Price))
head(a15)
##   Max.Price MPG.city MPG.highway
## 1      18.8       25          31
## 2      38.7       18          25
## 3      32.3       20          26
## 4      44.6       19          26
## 5      36.2       22          30
## 6      17.3       22          31
# 또는
a16 <- Cars93_1 %>%
         select(-(1:5))
head(a16)         
##   Max.Price MPG.city MPG.highway
## 1      18.8       25          31
## 2      38.7       18          25
## 3      32.3       20          26
## 4      44.6       19          26
## 5      36.2       22          30
## 6      17.3       22          31

4.3.4 컬럼 이름의 ’앞 부분’을 지정하여 선택

select(dataframe, starts_with(“xx_name”))

  • dataframe : 데이터 세트
  • starts_with(“xx_name”) :컬럼 이름이 “xx_name”으로 시작하는 모든 컬럼 선택

select() 함수의 인수로 starts_with() 를 사용하여 “xx_name”으로 시작하는 모든 컬럼을 선택할 수 있다.

Cars93_1 데이터 프레임에서 “MPG”로 시작하는 모든 변수를 선택해 보자.

# select(dataframe, starts_with("xx_name"))
#  : select all variables, starting with a "xx_name" prefix
a17 <- select(Cars93_1, starts_with("MPG"))
head(a17)
##   MPG.city MPG.highway
## 1       25          31
## 2       18          25
## 3       20          26
## 4       19          26
## 5       22          30
## 6       22          31
# 또는
a18 <- Cars93_1 %>%
         select(starts_with("MPG"))
head(a18)
##   MPG.city MPG.highway
## 1       25          31
## 2       18          25
## 3       20          26
## 4       19          26
## 5       22          30
## 6       22          31
  • MPG”로 시작하는 컬럼으로 “MPG.city”(도시 연비), “MPG.highway”(고속도로 연비) 두 개의 컬럼이 출력된다.

4.3.5 컬럼 이름의 ’끝 부분’을 지정하여 선택

select(dataframe, ends_with(“xx_name”))

  • dataframe : 데이터 세트
  • ends_with(“xx_name”) :컬럼 이름이 “xx_name”으로 끝나는 모든 컬럼 선택

starts_with() 있으면 ends_with()도 있다. “xx_name”으로 끝나는 모든 컬럼을 선택하고 싶다면 select() 함수 안에 인수로 ends_with() 를 추가해주면 된다.

Cars93_1 데이터 프레임에서 “Price”로 끝나는 모든 변수를 선택해 보자

# select(dataframe, ends_with("xx_name")) 
#   : select all variables, ending with a "xx_name" prefix 
a19 <- select(Cars93_1, ends_with("Price"))
head(a19)
##   Min.Price Price Max.Price
## 1      12.9  15.9      18.8
## 2      29.2  33.9      38.7
## 3      25.9  29.1      32.3
## 4      30.8  37.7      44.6
## 5      23.7  30.0      36.2
## 6      14.2  15.7      17.3
# 또는
a20 <- Cars93_1 %>%
         select(ends_with("Price"))
head(a20)
##   Min.Price Price Max.Price
## 1      12.9  15.9      18.8
## 2      29.2  33.9      38.7
## 3      25.9  29.1      32.3
## 4      30.8  37.7      44.6
## 5      23.7  30.0      36.2
## 6      14.2  15.7      17.3
  • Price”로 끝나는 컬럼이 “Min.Price,” “Price,” “Max.Price” 등 3개가 있음을 알 수 있다.

4.3.6 컬럼 이름의 일부를 포함하는 컬럼 선택

select(dataframe, contains(“xx_name”))

  • dataframe : 데이터 세트
  • contains(“xx_name”) : 컬럼 이름이 “xx_name”을 포함하는 모든 컬럼 선택

select() 함수에 contains() 인수를 사용하면 특정 문자열을 포함하는 모든 컬럼을 선택할 수 있다.

이때 “xx_name”은 대소문자를 구분하지 않는다.

Cars93_1 데이터 프레임에 있는 컬럼들 중에서 “P”를 포함하는 모든 컬럼을 선택해 보자.

# select(dataframe, contains("xx_string")) 
#   : select all variables which contains a "xx_string" literal string 
a21 <- select(Cars93_1, contains("P"))
head(a21)
##      Type Min.Price Price Max.Price MPG.city MPG.highway
## 1   Small      12.9  15.9      18.8       25          31
## 2 Midsize      29.2  33.9      38.7       18          25
## 3 Compact      25.9  29.1      32.3       20          26
## 4 Midsize      30.8  37.7      44.6       19          26
## 5 Midsize      23.7  30.0      36.2       22          30
## 6 Midsize      14.2  15.7      17.3       22          31
# 또는
a22 <- Cars93_1 %>%
         select(contains("P"))
head(a22)
##      Type Min.Price Price Max.Price MPG.city MPG.highway
## 1   Small      12.9  15.9      18.8       25          31
## 2 Midsize      29.2  33.9      38.7       18          25
## 3 Compact      25.9  29.1      32.3       20          26
## 4 Midsize      30.8  37.7      44.6       19          26
## 5 Midsize      23.7  30.0      36.2       22          30
## 6 Midsize      14.2  15.7      17.3       22          31
  • P”를 포함하는 컬럼으로 “Type”(소문자 ‘p’ 포함, 대소문자 구분 안함), “Min.Price,” “Price,” “Max.Price,” “MPG.city,” “MPG.highway” 등 총 6개의 컬럼이 있다.

4.3.7 정규 표현식과 일치하는 문자열을 포함하는 컬럼 선택

select(dataframe, matches(“.xx_string.”))

  • dataframe : 데이터 세트

  • matches(“.xx_string.”) : 정규 표현식과 일치하는 문자열이 포함된 모든 컬럼 선택

여기서도 대소문자는 구분하지 않는다. 정규 표현식(regular expressions)에 대해서는 추후에 학습하기로 한다.

Cars93_1의 데이터 프레임에 있는 컬럼 중 그 이름의 중간에 “P”를 포함하는(정규표현식 - “.P.”) 모든 컬럼을 선택해 보자.

# select(dataframe, matches(".xx_string.")) 
#   : Select columns that match a regular expression 
a23 <- select(Cars93_1, matches(".P.")); head(a23)
##      Type Min.Price Max.Price MPG.city MPG.highway
## 1   Small      12.9      18.8       25          31
## 2 Midsize      29.2      38.7       18          25
## 3 Compact      25.9      32.3       20          26
## 4 Midsize      30.8      44.6       19          26
## 5 Midsize      23.7      36.2       22          30
## 6 Midsize      14.2      17.3       22          31
a24 <- select(Cars93_1, matches("P")); head(a24)           # exactly the same with contains("P")
##      Type Min.Price Price Max.Price MPG.city MPG.highway
## 1   Small      12.9  15.9      18.8       25          31
## 2 Midsize      29.2  33.9      38.7       18          25
## 3 Compact      25.9  29.1      32.3       20          26
## 4 Midsize      30.8  37.7      44.6       19          26
## 5 Midsize      23.7  30.0      36.2       22          30
## 6 Midsize      14.2  15.7      17.3       22          31
# 또는
a25 <- Cars93_1 %>%
         select(matches(".P."))
head(a25)
##      Type Min.Price Max.Price MPG.city MPG.highway
## 1   Small      12.9      18.8       25          31
## 2 Midsize      29.2      38.7       18          25
## 3 Compact      25.9      32.3       20          26
## 4 Midsize      30.8      44.6       19          26
## 5 Midsize      23.7      36.2       22          30
## 6 Midsize      14.2      17.3       22          31
a26 <- Cars93_1 %>%
         select(matches("P"))
head(a26)
##      Type Min.Price Price Max.Price MPG.city MPG.highway
## 1   Small      12.9  15.9      18.8       25          31
## 2 Midsize      29.2  33.9      38.7       18          25
## 3 Compact      25.9  29.1      32.3       20          26
## 4 Midsize      30.8  37.7      44.6       19          26
## 5 Midsize      23.7  30.0      36.2       22          30
## 6 Midsize      14.2  15.7      17.3       22          31
  • 위에 match() 옵션 안에 첫 예제는 (“.P.”)를, 두번 째 예제는 점이 없이 (“P”)를 사용했다.

  • 앞 뒤로 .’(dot) 을 붙이면 시작과 끝 말고 컬럼명의 중간에 특정 문자열이 포함된 컬럼을 선택하라는 뜻이다.

  • matches(".P.") 로 한 경우에는 “P”로 시작하는 “Price” 컬럼이 선택되지 않지만, 그냥 matches("P")로 한 경우는 “P”로 시작하는 “Price” 컬럼도 포함되어 있음을 알 수 있다.

  • 참고로, ‘.’(dot) 이 없이 matches()를 쓰면 contains() 와 동일한 결과를 반환합니다.

4.3.8 원하는 컬럼 명의 그룹에 포함된 컬럼 선택

select(dataframe, one_of(vars))

  • dataframe : 데이터 세트
  • one_of(vars) : 컬럼 이름의 그룹(vars)에 포함된 모든 컬럼 선택

Cars93_1의 데이터 프레임 중에서 “Manufacturer,” “MAX.Price,” “MPG.highway” 등 3개의 컬럼 이름을 포함하는 컬럼 그룹이 있다고 할 때, Cars93_1 데이터 프레임에서 이 컬럼 그룹에 있는 컬럼이 있다면(<- 즉, 있을 수도 있지만 없을 수도 있다는 뜻임!) 모두 선택해 보자.

# select(dataframe, one_of(vars)) 
#   : Select columns that are from a group of names 
vars <- c("Manufacturer", "MAX.Price", "MPG.highway") 
a27 <- select(Cars93_1, one_of(vars))
## Warning: Unknown columns: `MAX.Price`
head(a27)
##   Manufacturer MPG.highway
## 1        Acura          31
## 2        Acura          25
## 3         Audi          26
## 4         Audi          26
## 5          BMW          30
## 6        Buick          31
# 또는
vars <- c("Manufacturer", "MAX.Price", "MPG.highway") 
a28 <- Cars93_1 %>%
         select(one_of(vars))
## Warning: Unknown columns: `MAX.Price`
head(a28)
##   Manufacturer MPG.highway
## 1        Acura          31
## 2        Acura          25
## 3         Audi          26
## 4         Audi          26
## 5          BMW          30
## 6        Buick          31
  • 위의 결과로 “MAX.Price”라는 컬럼에 대해서는 “Unknown variables”라고 해서 Warning mesage가 뜬다.

  • Cars93_1에 보면 “Max.Price”라는 컬럼은 있어도 “MAX.Price”라는 컬럼이 없다.이처럼 변수 그룹 vars 에 나열된 이름 중에서 데이터 프레임에 포함된 컬럼에 대해서는 선택되지만. 해당 컬럼이 없다면 Warning message를 보여준다.

반면에 그냥 select() 함수로 위의 컬럼 그룹을 선택해보면, 아래처럼 “Error: Can’t subset columns that don’t exist. x Column MAX.Price doesn’t exist.” error 메시지만 표시가 된다.

# select(Cars93_1, Manufacturer, MAX.Price, MPG.highway)

4.3.9 컬럼 이름의 접두사와 숫자 범위를 조합하여 컬럼 선택

select(dataframe, num_range("V", a:n))

  • dataframe : 데이터 세트
  • num_range("V", a:n): 접두사(“V”)와 숫자 범위(“a:n”)를 조합하여 Va 컬럼 부터 Vn 컬럼까지 선택

변수 이름이 동일하게 특정 접두사로 시작하는 데이터 프레임의 경우 이 기능을 유용하게 사용할 수 있다.

V1,” “V2,” “V3,” “V4” 등의 4개 변수를 가진 df 데이터 프레임에서 “V2,” “V3” 변수를 선택해 보자. 단, 이때 접두사 “V”와 숫자 범위 2:3 을 조합해서 쓰는 num_range() 옵션을 사용하면 다음과 같다.

# select(df, num_range("V", a:n)) 
#   : Select columns from num_range a to n with a prefix 
V1 <- c(rep(1, 10)) 
V2 <- c(rep(1:2, 5)) 
V3 <- c(rep(1:5, 2)) 
V4 <- c(rep(1:10)) 
df <- data.frame(V1, V2, V3, V4) 
df
##    V1 V2 V3 V4
## 1   1  1  1  1
## 2   1  2  2  2
## 3   1  1  3  3
## 4   1  2  4  4
## 5   1  1  5  5
## 6   1  2  1  6
## 7   1  1  2  7
## 8   1  2  3  8
## 9   1  1  4  9
## 10  1  2  5 10
a29 <- select(df, num_range("V", 2:3))
head(a29)
##   V2 V3
## 1  1  1
## 2  2  2
## 3  1  3
## 4  2  4
## 5  1  5
## 6  2  1
# 또는
a30 <- df %>%
   select(num_range("V", 2:3))
head(a30)
##   V2 V3
## 1  1  1
## 2  2  2
## 3  1  3
## 4  2  4
## 5  1  5
## 6  2  1