public bigdata

dplyr (버전업 + 몰랐던 내용 정리) 본문

R programming

dplyr (버전업 + 몰랐던 내용 정리)

public bigdata 2020. 3. 27. 23:15

※ dplyr은 3개 이상의 테이블 작업을 위한 기능을 제공하지 않는다. 대신 Advanced R에 설명된대로 purr::reduce() 또는 Reduce를 사용하여 두 테이블 동사를 반복적으로 결합하여 필요한만큼 많은 테이블을 처리할 수 있다.

 

# select vs mutate 

<select>

select는 열의 이름("변수명")과 위치를 지원한다.

select 함수는 select(var)이라고 작성했을 때 먼저 var이라는 변수명을 찾고 없으면, var이라는 변수를 평가하여 var에 담긴 변수의 위치값이나, 문자열을 받아서 변수를 찾는다.

## 예시1-Species로 작성했을 때 바로 변수명으로 인식한다. ##
> Species <- 3
> iris %>%
+   select(Species) %>% 
+   head(3)
  Species
1  setosa
2  setosa
3  setosa


## 예시2-select는 변수명도 그대로 인식한다 ##
> iris %>% 
+   select("Species") %>% 
+   head(3)
  Species
1  setosa
2  setosa
3  setosa


## 예시3-select는 위치를 인식한다 ##
> iris %>% 
+   select(5) %>% 
+   head(3)
  Species
1  setosa
2  setosa
3  setosa


## 예시4-select는 변수명도 그대로 인식한다 ##
## select(var)이라고 작성해서 var 변수를 찾아야 할 것 같지만
## tibble 내에 var이라는 변수가 없기 때문에, 다음 단계로
## var 객체를 찾아 "Species"라는 변수를 찾게되는 것으로 보인다.
> var <- "Species"
> iris %>% 
+   select(var) %>% 
+   head(3)
  Species
1  setosa
2  setosa
3  setosa


## 예시5 ##
## 만약 iris tibble에서 우리는 "Species"변수를 불러오고 싶은데
## iris tibble 내에 var이라는 변수가 있다면, "Species"를 불러오지 못할 것이다.
## 여기서 identity(var)를 통해서 var객체 내의 "Species"값을 불러와 원하는 결과를 얻을 수 있다.
> var <- "Species"
> iris %>% 
+   select(identity(var)) %>% 
+   head(3)
  Species
1  setosa
2  setosa
3  setosa

아래 처럼 코드를 작성해도 select 함수는 정상 작동된다. 그런데 vars가 변수명인지 변수명이나 변수의 위치를 담은 var 객체인지 헷갈릴 수 있다.(물론 select 함수는 우선 순위에 따라 오류없이 작동되지만.)

vars <- c("year", "month")
select(flights, vars, "day")
#> # A tibble: 336,776 x 3
#>    year month   day
#>   <int> <int> <int>
#> 1  2013     1     1
#> 2  2013     1     1
#> 3  2013     1     1
#> 4  2013     1     1
#> # … with 336,772 more rows

따라서 아래처럼 !!표현을 사용해서 vars가 변수명이 아니라 어떤 객체의 이름임을 알려준다.(표준평가를 하도록 한다)

# Let's create a new `vars` column:
flights$vars <- flights$year

# The new column won't be an issue if you evaluate `vars` in the
# context with the `!!` operator:
vars <- c("year", "month", "day")
select(flights, !! vars)
#> # A tibble: 336,776 x 3
#>    year month   day
#>   <int> <int> <int>
#> 1  2013     1     1
#> 2  2013     1     1
#> 3  2013     1     1
#> 4  2013     1     1
#> # … with 336,772 more rows

<mutate>

mutate는 select와 달리 mutate(df, "year", 2)라고 작성하면 해당 값이 열의 이름이나 위치를 나타내지 않고 백터객체를 나타내기 때문에 각각 "year", 2값을 가지는 '"year"', '2'열을 생성한다.


# group_by

<group_by>

group_by는 수정된 열로 그룹화할 수 있어서 편리하다.

group_by(df, month = as.factor(month))

그런데 아래처럼 작성하면 mutate는 열의 이름이나 위치를 지원하지 않기 때문에 '"month"'컬럼이 추가된다.

> group_by(iris, "month")
# A tibble: 150 x 6
# Groups:   "month" [1]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species `"month"`
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <chr>    
 1          5.1         3.5          1.4         0.2 setosa  month    
 2          4.9         3            1.4         0.2 setosa  month    
 3          4.7         3.2          1.3         0.2 setosa  month    
 4          4.6         3.1          1.5         0.2 setosa  month    
 5          5           3.6          1.4         0.2 setosa  month    

group_by_at을 사용하면 select와 같은 선택 방법을 사용할 수 있다.

> group_by_at(iris, vars(Sepal.Width:Species))
# A tibble: 150 x 5
# Groups:   Sepal.Width, Petal.Length, Petal.Width, Species [143]
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
 1          5.1         3.5          1.4         0.2 setosa 
 2          4.9         3            1.4         0.2 setosa 
 3          4.7         3.2          1.3         0.2 setosa 
 4          4.6         3.1          1.5         0.2 setosa 
 5          5           3.6          1.4         0.2 setosa 

select vs mutate에서 mutate는 열의 위치, 열 이름을 지원하지 않는다고 했는데, mutate_at은 select가 동작하는 그대로(select 함수는 select(var)이라고 작성했을 때 먼저 var이라는 변수명을 찾고 없으면, var이라는 변수를 평가하여 var에 담긴 변수의 위치값이나, 문자열을 받아서 변수를 찾는다.) 사용할 수 있다. 바로 vars()함수를 이용해서...

 

※ 그런데 select처럼 !!방법은 왜 사용할 수 없는 것인가?.... 너무 헷갈린다..

 

어쨋든 정리하자면. 1) select, mutate는 열을 선택하는 방법이 다르다. 2) mutate_at, group_by_at 에서는 위에 볼드처리한 것처럼 평가하여 컬럼 선택이 가능한 것으로 보인다. 3) select에서 사용하는 -컬럼명, 컬럼명1:컬럼명2 같은 변수선택 표현은 vars로 감싸야만 동작하는 것으로 보인다.

 

그리고 _at, _if, _all가 group_by, summarise, mutate 등의 함수에 다양하게 들어있는데

  • _at : 특정한 컬럼들에에 적용
  • _if : 특정 타입을 가지는 컬럼들에 적용
  • _all : 모든 컬럼에 적용

여기서 적용이란 말은 group_by, summarise, mutate 등 각 함수들의 기능이 적용된다는 말. 


<핵심적인 dplyr 기능 변화>

 

 

dplyr 1.0.0: working within rows - Tidyverse

 

www.tidyverse.org

주요하게 바뀐 내용은 rowwise, summarise, across 이 세가지로 보인다. 기타 변화들도 자잘하게 많은듯하다. 위 블로그 공부후에 아래에 추후 정리할 예정이다.

>https://github.com/tidyverse/dplyr/releases이 링크로 정리하면 다 될듯하다.