मैं कस्टम फ़ंक्शन लिखने के लिए rlang का उपयोग करने का प्रयास कर रहा हूं। हालांकि मैं ऐसा तब कर सकता हूं जब फ़ंक्शन में data तर्क शामिल होता है, मुझे परेशानी होती है कि जब फ़ंक्शन को वैक्टर की आवश्यकता होती है और मुझे $ ऑपरेटर का उपयोग करने की आवश्यकता होती है, तो मुझे ठीक से क्वासीकोटेशन का उपयोग कैसे करना चाहिए।

यहाँ एक खिलौना उदाहरण है-

library(tidyverse)

# proper implementation
tryfn <- function(data, x, y) {
  # creating a dataframe
  data <-
    dplyr::select(
      .data = data,
      !!rlang::enquo(x),
      !!rlang::enquo(y)
    ) %>% # dropping unused levels
    dplyr::mutate(.data = ., 
                  !!rlang::enquo(x) := droplevels(as.factor(!!rlang::enquo(x))))

  # checking if data is getting imported properly
  print(data)

  # figuring out number of levels in the grouping factor
  return(length(levels(data$`!!rlang::enquo(x)`))[[1]])
}

# using the function
tryfn(ggplot2::msleep, vore, brainwt)

#> # A tibble: 83 x 2
#>    vore   brainwt
#>    <fct>    <dbl>
#>  1 carni NA      
#>  2 omni   0.0155 
#>  3 herbi NA      
#>  4 omni   0.00029
#>  5 herbi  0.423  
#>  6 herbi NA      
#>  7 carni NA      
#>  8 <NA>  NA      
#>  9 carni  0.07   
#> 10 herbi  0.0982 
#> # ... with 73 more rows

#> Warning: Unknown or uninitialised column: '!!rlang::enquo(x)'.
#> [1] 0

जैसा कि यहां देखा जा सकता है, डेटा ठीक से आयात हो रहा है, लेकिन return मान गलत है क्योंकि मैं $ ऑपरेटर के संदर्भ में quasiquotation का उपयोग नहीं करता हूं। मैं यह कैसे कर सकता हूँ?

2
Indrajeet Patil 30 जून 2019, 18:09

2 जवाब

सबसे बढ़िया उत्तर

हम as_name के साथ character क्लास में कनवर्ट कर सकते हैं और [[ के साथ एक्सट्रेक्ट कर सकते हैं। enquo के साथ बार-बार रूपांतरण से बचने के लिए, इसे एक बार में करें, पहचानकर्ता में स्टोर करें और पुन: उपयोग करें

tryfn <- function(data, x, y) {
 x <- rlang::enquo(x)
 y <- rlang::enquo(y)
  # creating a dataframe
  data <-
    dplyr::select(
      .data = data,
      !!x,
      !!y
    ) %>% # dropping unused levels
    dplyr::mutate(.data = ., 
                  !!x := droplevels(as.factor(!!x)))

  # checking if data is getting imported properly
  print(data)

  # figuring out number of levels in the grouping factor
  return(length(levels(data[[rlang::as_name(x)]]))[[1]])

}

-परिक्षण

tryfn(ggplot2::msleep, vore, brainwt)
# A tibble: 83 x 2
#   vore   brainwt
#   <fct>    <dbl>
# 1 carni NA      
# 2 omni   0.0155 
# 3 herbi NA      
# 4 omni   0.00029
# 5 herbi  0.423  
# 6 herbi NA      
# 7 carni NA      
# 8 <NA>  NA      
# 9 carni  0.07   
#10 herbi  0.0982 
# … with 73 more rows
#[1] 4
4
akrun 30 जून 2019, 18:35

आप select के समान शब्दार्थ का उपयोग करके एक कॉलम निकालने के लिए dplyr::pull का उपयोग कर सकते हैं। इंटरपोलेशन के लिए rlang 0.4's {{...}} का उपयोग करना (enquo और !! एक में) और थोड़ा सरल करना,

library(tidyverse)

tryfn <- function(data, x, y) {
    data <- data %>% transmute({{x}} := as.factor({{x}}), {{y}})

    print(data)

    data %>% pull({{x}}) %>% nlevels()
}

tryfn(ggplot2::msleep, vore, brainwt)
#> # A tibble: 83 x 2
#>    vore   brainwt
#>    <fct>    <dbl>
#>  1 carni NA      
#>  2 omni   0.0155 
#>  3 herbi NA      
#>  4 omni   0.00029
#>  5 herbi  0.423  
#>  6 herbi NA      
#>  7 carni NA      
#>  8 <NA>  NA      
#>  9 carni  0.07   
#> 10 herbi  0.0982 
#> # … with 73 more rows
#> [1] 4
1
alistaire 30 जून 2019, 20:58