다른 테이블을 기반으로 데이터 프레임의 변수 클래스를 변환하는 사용자 지정 함수 작성
Jan 03 2021
받아 들일 수있는 함수를 작성하려고 해요 :
df_1
열의 클래스를 변환해야하는 데이터 프레임 ( )- 각 변수에 대한 행
df_2
이있는 다른 데이터 프레임 ( )df_1
df_2
각 변수df_1
가 변환되어야 하는 클래스를 지정 하는 열
예
1-데이터 프레임 ( df_1
)과 내 데이터 (및 변환 할 변수의 클래스)
library(tibble)
library(dplyr)
set.seed(2021)
df_1 <-
tibble(name = c("john", "jack", "mary", "matt", "elizabeth", "richard", "carlos", "george", "ferdinand", "william"),
height = sample(155:200, size = 10),
weight = sample(50:100, size = 10),
age = sample(20:100, size = 10),
gender = sample(c("male", "female"), size = 10, replace = TRUE),
preferred_pet = sample(c("dog", "cat", "frog", "rabbit"), size= 10, replace = TRUE)) %>%
mutate(across(everything(), as.character))
## # A tibble: 10 x 6
## name height weight age gender preferred_pet
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 john 161 100 38 female frog
## 2 jack 192 67 87 female dog
## 3 mary 193 52 24 male rabbit
## 4 matt 166 95 92 male dog
## 5 elizabeth 160 89 82 female cat
## 6 richard 199 75 57 male dog
## 7 carlos 195 85 37 female rabbit
## 8 george 159 86 62 male rabbit
## 9 ferdinand 177 71 78 female cat
## 10 william 197 80 89 female rabbit
2- 열을 df_2
변환 할 클래스가있는 데이터 프레임 ( )df_1
set.seed(2021)
df_2 <-
tibble(var_name = c("name", "height", "weight", "gender", "preferred_pet", "record_creation"),
var_class = c("character", "numeric", "numeric", "factor", "factor", "datetime")) %>%
slice(sample(1:n()))
## # A tibble: 6 x 2
## var_name var_class
## <chr> <chr>
## 1 weight numeric
## 2 record_creation datetime
## 3 height numeric
## 4 name character
## 5 gender factor
## 6 preferred_pet factor
3-클래스 변환을위한 함수 빌드
나는 여기 에서 @akrun의 솔루션을 보았는데 , 이는 내가 달성하려는 것과 매우 가까운 것 같습니다.
library(purrr)
library(stringr)
my_df <- iris
my_types <- c("factor", "character", "double", "logical", "character")
my_df[] <- map2(my_df, str_c("as.", my_types), ~ get(.y)(.x))
그러나이 솔루션은 변수 이름이에 df_1
반드시 표시 되지 않고에서 반드시 표시되지 않는 변수를 포함하는 저 df_2
와 같은 상황을 해결하지 않습니다 .df_2$var_name
df_1
df_1
에서 찾은 정보에 따라의 vars 클래스 를 변환하는 함수를 구성하는 아이디어에 대해 기뻐할 것 입니다 df_2
. tidyverse
함수를 사용하여 솔루션을 찾는 것이 이상적입니다. 감사!
답변
1 IanCampbell Jan 03 2021 at 00:26
다음을 활용하는 접근 방식은 다음 across
과 cur_column
같습니다.
library(dplyr) #version >= 1.0.0
df_1 %>%
mutate(across(any_of(df_2$var_name), ~get(paste0("as.",df_2[df_2$var_name == cur_column(),"var_class"]))(.x)))
# A tibble: 10 x 6
name height weight age gender preferred_pet
<chr> <dbl> <dbl> <chr> <fct> <fct>
1 john 161 100 38 female frog
2 jack 192 67 87 female dog
3 mary 193 52 24 male rabbit
4 matt 166 95 92 male dog
5 elizabeth 160 89 82 female cat
6 richard 199 75 57 male dog
7 carlos 195 85 37 female rabbit
8 george 159 86 62 male rabbit
9 ferdinand 177 71 78 female cat
10 william 197 80 89 female rabbit
any_of
만에 존재하는 mutate 컬럼에 시도 할 것을 선택 도우미 보험 상품 df_2
.
두 번째 인수는 존재하는 열에 적용되는 함수입니다. 를 사용 cur_column()
하여 변경되는 열의 이름에 액세스 할 수 있습니다 . 거기에서 우리는 그 열 이름을 찾고 원하는 것을 df_2
반환합니다 var_class
. 그런 다음 get()
기본 R에서 사용 하여 적절한 함수를 반환하고 (.x)
.
함수를 정의하고 다른 tidyverse 함수와 마찬가지로 따옴표없이 열 이름을 전달하려면 다음을 사용할 수 있습니다 rlang::enquo
.
library(rlang)
change_class_by_table <- function(data,data_ref,column_name,column_class){
data %>%
mutate(across(any_of(pull(data_ref,!!enquo(column_name))),
~get(paste0("as.",filter(data_ref, !!enquo(column_name) == cur_column()) %>%
pull(!!enquo(column_class))))(.x)))
}
change_class_by_table(df_1,df_2,var_name,var_class)
## A tibble: 10 x 6
# name height weight age gender preferred_pet
# <chr> <dbl> <dbl> <chr> <fct> <fct>
# 1 john 161 100 38 female frog
# 2 jack 192 67 87 female dog
# 3 mary 193 52 24 male rabbit
# ...