किसी अन्य तालिका के आधार पर डेटाफ़्रेम में चर के वर्ग को बदलने के लिए एक कस्टम फ़ंक्शन लिखना
मैं एक फंक्शन लिखने की कोशिश कर रहा हूँ जो इसमें हो सकता है:
- डेटा फ्रेम (
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 - वर्ग रूपांतरण के लिए एक समारोह का निर्माण
मैंने यहाँ @ arrun का समाधान देखा है , जो मुझे प्राप्त करने की कोशिश कर रहा है, उसके काफी करीब लगता है।
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
मिली जानकारी के अनुसार किसी भी विचार के लिए एक समारोह के निर्माण के लिए किसी भी विचार के लिए खुशी होगी df_2
। tidyverse
फ़ंक्शन का उपयोग करके समाधान खोजना आदर्श होगा। धन्यवाद!
जवाब
यहाँ एक दृष्टिकोण लाभकारी है 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
चयन सहायक सुनिश्चित करता है कि आप केवल मे बदलें कॉलम कि में मौजूद हैं करने की कोशिश df_2
।
दूसरा तर्क वह फ़ंक्शन है जो मौजूद कॉलमों पर लागू होता है। आप cur_column()
म्यूट किए जा रहे कॉलम के नाम तक पहुंच का उपयोग कर सकते हैं । वहाँ से, हम अभी उस कॉलम का नाम देखते हैं df_2
और var_class
आप चाहते हैं। फिर get()
उपयुक्त फ़ंक्शन को वापस करने के लिए आधार आर से उपयोग करें और उस कॉलम के साथ लागू करें (.x)
।
यदि आप किसी फ़ंक्शन को परिभाषित करना चाहते हैं, और अन्य नाम के रूप में स्तंभ कार्यों को पास कर दें, तो आप उपयोग कर सकते हैं 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
# ...