मैं dtplyr के साथ क्या नहीं कर सकता कि मैं data.table में कर सकता हूं


10

क्या मुझे विशेष रूप से dplyr, dtplyrऔर , के बीच , आर में डेटा के लिए अपने सीखने के प्रयास को निवेश करना चाहिए data.table?

  • मैं dplyrज्यादातर उपयोग करता हूं , लेकिन जब डेटा उसके लिए बहुत बड़ा होता है, तो मैं उपयोग करूंगा data.table, जो एक दुर्लभ घटना है। तो अब dtplyrv1.0 एक अंतरफलक के रूप में बाहर है data.table, सतह पर ऐसा लगता है कि मुझे कभी data.tableभी इंटरफ़ेस का उपयोग करने के बारे में फिर से चिंता करने की आवश्यकता नहीं है ।

  • तो उस समय का उपयोग क्या नहीं किया जा सकता है data.tableकि सबसे उपयोगी विशेषताएं या पहलू हैं, और इस संभावना के साथ कभी नहीं किया जाएगा ?dtplyrdtplyr

  • इसके चेहरे पर, dplyrलाभ के साथ data.tableयह ध्वनि की तरह dtplyrआगे निकल जाएगा dplyr। उपयोग करने के लिए किसी भी कारण नहीं होगा dplyrएक बार dtplyrपूरी तरह से परिपक्व हो गया है?

नोट: मैं dplyrबनाम के बारे में नहीं पूछ रहा हूं data.table(जैसा कि data.table vs dplyr में है: एक व्यक्ति कुछ अच्छा कर सकता है दूसरा खराब नहीं कर सकता है? ), लेकिन यह देखते हुए कि एक को किसी विशेष समस्या के लिए पसंद किया जाता है, क्यों नहीं होगा ' टी dtplyrका उपयोग करने के लिए उपकरण हो।


1
वहाँ कुछ है आप अच्छी तरह से में कर सकते हैं dplyrकि आप में अच्छी तरह से नहीं कर सकते data.table? यदि नहीं, तो स्विचिंग इससे data.tableबेहतर होने वाला है dtplyr
सिंदरी_बलदुर

2
से dtplyrरीडमी, 'कुछ data.tableभाव कोई सीधा है dplyrबराबर। उदाहरण के लिए, क्रॉस-या रोलिंग-जॉइन को व्यक्त करने का कोई तरीका नहीं है dplyr। ' और ' dplyrशब्दार्थ से मेल खाने के लिए , mutate() डिफ़ॉल्ट रूप से जगह में संशोधित नहीं होता है। इसका मतलब है कि इसमें शामिल अधिकांश अभिव्यक्तियों को mutate()एक प्रतिलिपि बनाना होगा जो कि यदि आप data.tableसीधे उपयोग कर रहे हैं तो यह आवश्यक नहीं होगा । ' वहाँ है कि दूसरे भाग के आसपास एक रास्ता है, लेकिन कितनी बार mutateउपयोग किया जाता है, यह देखते हुए कि मेरी आँखों में एक बहुत बड़ा नकारात्मक है।
क्लेनिक्सस्टैट्स

जवाबों:


16

मैं अपना सर्वश्रेष्ठ मार्गदर्शक देने की कोशिश करूंगा लेकिन यह आसान नहीं है क्योंकि किसी को {data.table}, {dplyr}, {dtplyr} और साथ ही {base R} सभी से परिचित होना होगा। मैं {data.table} और कई {tidy-world} पैकेज ({dplyr} को छोड़कर) का उपयोग करता हूं। दोनों से प्यार, हालांकि मैं dplyr करने के लिए data.table का वाक्यविन्यास पसंद करता हूं। मुझे आशा है कि सभी सुव्यवस्थित संकुल जब भी आवश्यक होंगे {dtplyr} या {data.table} बैकएंड के रूप में उपयोग करेंगे।

किसी भी अन्य अनुवाद के साथ (जैसा कि dplyr-to-sparkly / SQL), ऐसी चीजें हैं जिनका अनुवाद किया जा सकता है या नहीं, कम से कम अब तक। मेरा मतलब है, शायद एक दिन {dtplyr} इसे 100% अनुवादित कर सकता है, कौन जानता है। नीचे दी गई सूची संपूर्ण नहीं है और न ही यह 100% सही है क्योंकि मैं संबंधित विषयों / पैकेजों / मुद्दों आदि पर अपने ज्ञान के आधार पर उत्तर देने की पूरी कोशिश करूंगा।

महत्वपूर्ण रूप से, उन उत्तरों के लिए जो पूरी तरह से सही नहीं हैं, मुझे आशा है कि यह आपको कुछ दिशानिर्देश देता है कि {data.table} के किन पहलुओं पर आपको ध्यान देना चाहिए और, इसकी तुलना {dtplyr} से करें और खुद ही उत्तरों का पता लगाएं। इन जवाबों के लिए अनुमति न लें।

और, मुझे आशा है कि इस पोस्ट का उपयोग सभी {dplyr}, {data.table} या {dtplyr} उपयोगकर्ताओं / रचनाकारों के लिए चर्चा और सहयोग के लिए किया जा सकता है और #RStats को और भी बेहतर बनाया जा सकता है।

{data.table} का उपयोग न केवल तेज और मेमोरी कुशल संचालन के लिए किया जाता है। कई लोग हैं, जिनमें स्वयं भी शामिल हैं, {data.table} के सुरुचिपूर्ण सिंटैक्स पसंद करते हैं। इसमें frollapplyसी में लिखे गए टाइम-सीरीज़ फ़ंक्शंस जैसे रोलिंग-फ़ैमिली (यानी ) जैसे अन्य तेज़ संचालन भी शामिल हैं । इसका उपयोग किसी भी फ़ंक्शंस के साथ किया जा सकता है, जिसमें tidyverse भी शामिल है। मैं {data.table} + {purrr} का बहुत उपयोग करता हूं!

संचालन की जटिलता

इसका आसानी से अनुवाद किया जा सकता है

library(data.table)
library(dplyr)
library(flights)
data <- data.table(diamonds)

# dplyr 
diamonds %>%
  filter(cut != "Fair") %>% 
  group_by(cut) %>% 
  summarize(
    avg_price    = mean(price),
    median_price = as.numeric(median(price)),
    count        = n()
  ) %>%
  arrange(desc(count))

# data.table
data [
  ][cut != 'Fair', by = cut, .(
      avg_price    = mean(price),
      median_price = as.numeric(median(price)),
      count        = .N
    )
  ][order( - count)]

{data.table} बहुत तेज़ और मेमोरी कुशल है क्योंकि (लगभग?) सब कुछ जमीन से C से अपडेट-बाय-रेफरेंस , कुंजी (थिंक एसक्यूएल) की प्रमुख अवधारणाओं के साथ बनाया गया है , और पैकेज में हर जगह उनका अथक अनुकूलन है। (यानी fifelse, fread/freadबेस आर द्वारा अपनाया गया मूलांक क्रम), जबकि सिंटैक्स संक्षिप्त और सुसंगत है, इसलिए मुझे लगता है कि यह सुरुचिपूर्ण है।

से परिचय data.table लिए , इस तरह के रूप में मुख्य डेटा हेरफेर आपरेशनों सबसेट, समूह, अद्यतन, में शामिल होने, आदि के लिए एक साथ रखा जाता है

  • संक्षिप्त और सुसंगत वाक्य रचना ...

  • प्रत्येक ऑपरेशन को मैप करने के संज्ञानात्मक बोझ के बिना द्रव का विश्लेषण करना ...

  • स्वचालित रूप से प्रत्येक ऑपरेशन के लिए आवश्यक डेटा को जानने के द्वारा आंतरिक रूप से और बहुत प्रभावी ढंग से स्वचालित रूप से अनुकूलन करना, बहुत तेज और मेमोरी कुशल कोड के लिए अग्रणी है

अंतिम बिंदु, उदाहरण के लिए,

# Calculate the average arrival and departure delay for all flights with “JFK” as the origin airport in the month of June.
flights[origin == 'JFK' & month == 6L,
        .(m_arr = mean(arr_delay), m_dep = mean(dep_delay))]
  • हम पहली बार इनसेट में मिलते हैं जो कि मैचिंग पंक्ति सूचकांकों को खोजने के लिए है जहां मूल हवाई अड्डे "JFK" के बराबर है, और महीने 6L के बराबर है। हम अभी तक उन पंक्तियों के अनुसार पूरे डेटाटेबल को सब्मिट नहीं करते हैं।

  • अब, हम j को देखते हैं और पाते हैं कि यह केवल दो कॉलम का उपयोग करता है। और हमें जो करना है, उनका मतलब () की गणना करना है। इसलिए हम मिलान पंक्तियों के अनुरूप केवल उन कॉलमों को सब्मिट करते हैं, और उनके माध्य () की गणना करते हैं।

क्योंकि क्वेरी के तीन मुख्य घटक (i, j और by) एक साथ हैं [...] , data.table तीनों को देख सकते हैं और मूल्यांकन से पहले क्वेरी को पूरी तरह से अनुकूलित कर सकते हैं, प्रत्येक अलग से नहीं । इसलिए हम गति और मेमोरी दक्षता दोनों के लिए संपूर्ण उप सबसेट (यानी, arr_delay और dep_delay के अलावा कॉलम को हटाते हुए) से बचने में सक्षम हैं।

यह देखते हुए कि, {data.table} के लाभों को पुनः प्राप्त करने के लिए, {dtplr} का अनुवाद उस संदर्भ में सही होना चाहिए। संचालन जितना जटिल होगा, अनुवाद उतना ही कठिन होगा। ऊपर जैसे सरल ऑपरेशन के लिए, यह निश्चित रूप से आसानी से अनुवादित किया जा सकता है। जटिल लोगों के लिए, या {dtplyr} द्वारा समर्थित नहीं हैं, आपको अपने आप को ऊपर बताए अनुसार ढूंढना होगा, अनुवादित वाक्यविन्यास और बेंचमार्क की तुलना करने और परिचित संबंधित पैकेजों की तुलना करने के लिए।

जटिल संचालन या असमर्थित संचालन के लिए, मैं नीचे कुछ उदाहरण प्रदान करने में सक्षम हो सकता हूं। फिर, मैं बस अपनी पूरी कोशिश कर रहा हूं। मुझ पर कोमल बनो।

अद्यतन-दर-संदर्भ

मैं इंट्रो / विवरण में नहीं जाऊंगा लेकिन यहां कुछ लिंक दिए गए हैं

मुख्य संसाधन: संदर्भ शब्दार्थ

अधिक विवरण: जब डेटाटेबल बिल्कुल समझ में आता है, तो किसी अन्य डेटा का संदर्भ (बनाम कॉपी)

मेरी राय में, अपडेट-बाय-रेफरेंस , {data.table} की सबसे महत्वपूर्ण विशेषता है और यही इसे इतनी तेज और मेमोरी कुशल बनाती है। dplyr::mutateडिफ़ॉल्ट रूप से इसका समर्थन नहीं करता है। जैसा कि मैं {dtplyr} से परिचित नहीं हूं, मुझे यकीन नहीं है कि {dtplyr} द्वारा कितना और क्या संचालन किया जा सकता है या इसका समर्थन नहीं किया जा सकता है। जैसा कि ऊपर उल्लेख किया गया है, यह संचालन की जटिलता पर भी निर्भर करता है, जो अनुवादों को प्रभावित करता है।

{Data.table} में अद्यतन-दर-संदर्भ का उपयोग करने के दो तरीके हैं

  • {data.table} का असाइनमेंट ऑपरेटर :=

  • set-family: set, setnames, setcolorder, setkey, setDT, fsetdiff, और कई और अधिक

:=की तुलना में अधिक सामान्यतः उपयोग किया जाता है set। जटिल और बड़े डेटासेट के लिए, अद्यतन-दर-संदर्भ शीर्ष गति और मेमोरी दक्षता प्राप्त करने की कुंजी है। सोचने का आसान तरीका (100% सटीक नहीं है, क्योंकि विवरण इससे कहीं अधिक जटिल हैं क्योंकि इसमें हार्ड / उथले कॉपी और कई अन्य कारक शामिल हैं), कहते हैं कि आप 10GB के बड़े डेटासेट के साथ काम कर रहे हैं, जिसमें 10 कॉलम और 1GB हैं । एक कॉलम में हेरफेर करने के लिए, आपको केवल 1GB से निपटने की आवश्यकता है।

मुख्य बिंदु यह है कि अद्यतन-दर-संदर्भ के साथ , आपको केवल आवश्यक डेटा से निपटना होगा। इसीलिए {data.table} का उपयोग करते समय, विशेष रूप से बड़े डेटासेट के साथ काम करते हुए, हम जब भी संभव हो अपडेट-बाय-संदर्भ का उपयोग करते हैं। उदाहरण के लिए, बड़े मॉडलिंग डाटासेट में हेरफेर

# Manipulating list columns

df <- purrr::map_dfr(1:1e5, ~ iris)
dt <- data.table(df)

# data.table
dt [,
    by = Species, .(data   = .( .SD )) ][,  # `.(` shorthand for `list`
    model   := map(data, ~ lm(Sepal.Length ~ Sepal.Width, data = . )) ][,
    summary := map(model, summary) ][,
    plot    := map(data, ~ ggplot( . , aes(Sepal.Length, Sepal.Width)) +
                           geom_point())]

# dplyr
df %>% 
  group_by(Species) %>% 
  nest() %>% 
  mutate(
    model   = map(data, ~ lm(Sepal.Length ~ Sepal.Width, data = . )),
    summary = map(model, summary),
    plot    = map(data, ~ ggplot( . , aes(Sepal.Length, Sepal.Width)) +
                          geom_point())
  )

घोंसले के संचालन का list(.SD)समर्थन {dtlyr} द्वारा नहीं किया जा सकता है जैसा कि उपयोगकर्ता द्वारा उपयोग किया जाता है tidyr::nest? इसलिए मुझे यकीन नहीं है कि यदि बाद के ऑपरेशनों को {data.table} के रूप में अनुवादित किया जा सकता है तो तेज और कम मेमोरी है।

नोट: data.table का परिणाम "मिलीसेकंड" में है, "मिनट" में dplyr

df <- purrr::map_dfr(1:1e5, ~ iris)
dt <- copy(data.table(df))

bench::mark(
  check = FALSE,

  dt[, by = Species, .(data = list(.SD))],
  df %>% group_by(Species) %>% nest()
)
# # A tibble: 2 x 13
#   expression                                   min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc
#   <bch:expr>                              <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>
# 1 dt[, by = Species, .(data = list(.SD))] 361.94ms 402.04ms   2.49      705.8MB     1.24     2     1
# 2 df %>% group_by(Species) %>% nest()        6.85m    6.85m   0.00243     1.4GB     2.28     1   937
# # ... with 5 more variables: total_time <bch:tm>, result <list>, memory <list>, time <list>,
# #   gc <list>

अद्यतन-दर-संदर्भ और यहां तक ​​कि {data.table} के कई उपयोग-मामले हैं, उपयोगकर्ता हर समय इसके उन्नत संस्करण का उपयोग नहीं करेंगे क्योंकि इसके लिए अधिक कोड की आवश्यकता होती है। क्या {dtplyr} इन आउट-ऑफ-द-बॉक्स का समर्थन करते हैं, आपको स्वयं पता लगाना होगा।

एक ही फ़ंक्शन के लिए एकाधिक अद्यतन-दर-संदर्भ

मुख्य संसाधन: सुरुचिपूर्ण ढंग से डेटा में कई कॉलम असाइन करना। lapply () के साथ

इसमें या तो अधिक इस्तेमाल किया जाता है :=या set

dt <- data.table( matrix(runif(10000), nrow = 100) )

# A few variants

for (col in paste0('V', 20:100))
  set(dt, j = col, value = sqrt(get(col)))

for (col in paste0('V', 20:100))
  dt[, (col) := sqrt(get(col))]

# I prefer `purrr::map` to `for`
library(purrr)
map(paste0('V', 20:100), ~ dt[, (.) := sqrt(get(.))])

{Data.table} मैट डॉवेल के निर्माता के अनुसार

(ध्यान दें कि बड़ी संख्या में स्तंभों की तुलना में बड़ी संख्या में लूप सेट करना अधिक सामान्य हो सकता है।)

Join + setkey + update-by-reference

मुझे अपेक्षाकृत बड़े डेटा के साथ तेजी से जुड़ने की जरूरत थी और हाल ही में इसी तरह के पैटर्न से जुड़ते हैं, इसलिए मैं सामान्य जोड़ के बजाय अपडेट-बाय-रेफरेंस की शक्ति का उपयोग करता हूं । जैसा कि उन्हें अधिक कोड की आवश्यकता होती है, मैं उन्हें पुन: प्रयोज्य और पठनीयता के लिए गैर-मानक मूल्यांकन के साथ निजी पैकेज में लपेटता हूं जहां मैं इसे कहता हूं setjoin

मैंने यहाँ कुछ बेंचमार्क किया: data.table join + update-by-reference + setkey

सारांश

# For brevity, only the codes for join-operation are shown here. Please refer to the link for details

# Normal_join
x <- y[x, on = 'a']

# update_by_reference
x_2[y_2, on = 'a', c := c]

# setkey_n_update
setkey(x_3, a) [ setkey(y_3, a), on = 'a', c := c ]

नोट: dplyr::left_joinयह भी परीक्षण किया गया था और यह ~ साथ धीमी 9,000 एमएस है, दोनों {data.table} की तुलना में अधिक स्मृति का उपयोग के update_by_referenceऔर setkey_n_update, लेकिन {data.table} से कम स्मृति का उपयोग के normal_join। इसमें लगभग ~ 2.0GB मेमोरी की खपत हुई। मैंने इसे शामिल नहीं किया क्योंकि मैं केवल {data.table} पर ध्यान केंद्रित करना चाहता हूं।

मुख्य निष्कर्ष

  • setkey + updateऔर क्रमशः update~ 11 और ~ 6.5 गुना अधिक तेज normal joinहैं
  • पहले में शामिल होने पर, के प्रदर्शन setkey + updateके समान है updateके रूप में की भूमि के ऊपर setkeyमोटे तौर पर अपने स्वयं के निष्पादन लाभ ऑफसेट
  • दूसरे और बाद में मिलती है पर, के रूप में setkeyकी आवश्यकता नहीं है, setkey + updateतेजी से है update(तेज़ या से ~ 1.8 गुना की normal join~ 11 बार से)

छवि

उदाहरण

प्रदर्शनकारी और स्मृति कुशल जोड़ के लिए, updateया तो उपयोग करें या setkey + update, जहां बाद अधिक कोड की कीमत पर तेज है।

आइए देखें कुछ छद्म कोड, संक्षिप्तता के लिए। लॉजिक्स समान हैं।

एक या कुछ स्तंभों के लिए

a <- data.table(x = ..., y = ..., z = ..., ...)
b <- data.table(x = ..., y = ..., z = ..., ...)

# `update`
a[b, on = .(x), y := y]
a[b, on = .(x),  `:=` (y = y, z = z, ...)]
# `setkey + update`
setkey(a, x) [ setkey(b, x), on = .(x), y := y ]
setkey(a, x) [ setkey(b, x), on = .(x),  `:=` (y = y, z = z, ...) ]

कई कॉलम के लिए

cols <- c('x', 'y', ...)
# `update`
a[b, on = .(x), (cols) := mget( paste0('i.', cols) )]
# `setkey + update`
setkey(a, x) [ setkey(b, x), on = .(x), (cols) := mget( paste0('i.', cols) ) ]

तेज और स्मृति के लिए आवरण कुशल जुड़ता है ... उनमें से कई ... समान जुड़ाव-पैटर्न के साथ, उन्हें setjoinऊपर की तरह लपेटें - साथ update - बिना या बिनाsetkey

setjoin(a, b, on = ...)  # join all columns
setjoin(a, b, on = ..., select = c('columns_to_be_included', ...))
setjoin(a, b, on = ..., drop   = c('columns_to_be_excluded', ...))
# With that, you can even use it with `magrittr` pipe
a %>%
  setjoin(...) %>%
  setjoin(...)

के साथ setkey, तर्क onछोड़ा जा सकता है। यह पठनीयता के लिए भी शामिल किया जा सकता है, विशेष रूप से दूसरों के साथ सहयोग करने के लिए।

बड़ी पंक्ति-संचालन

  • जैसा कि ऊपर बताया गया है, उपयोग करें set
  • अपनी तालिका को पूर्व-आबाद करें, अद्यतन-दर-संदर्भ तकनीकों का उपयोग करें
  • सबसेट का उपयोग कर (यानी setkey)

संबंधित संसाधन: किसी data.table ऑब्जेक्ट के अंत में संदर्भ द्वारा एक पंक्ति जोड़ें

अद्यतन-दर-संदर्भ का सारांश

ये अद्यतन-दर-संदर्भ के कुछ उपयोग के मामले हैं । और भी कई हैं।

जैसा कि आप देख सकते हैं, बड़े डेटा से निपटने के उन्नत उपयोग के लिए, बड़े डेटासेट के लिए अपडेट-बाय-रेफरेंस का उपयोग करते हुए कई उपयोग के मामले और तकनीकें हैं । {Data.table} में उपयोग करना इतना आसान नहीं है और क्या {dtplyr} इसका समर्थन करता है, आप स्वयं पता लगा सकते हैं।

मैं इस पोस्ट में अद्यतन-दर-संदर्भ पर ध्यान केंद्रित करता हूं क्योंकि मुझे लगता है कि यह तेज़ और मेमोरी कुशल संचालन के लिए {data.table} की सबसे शक्तिशाली विशेषता है। उस ने कहा, कई, कई अन्य पहलू हैं जो इसे बहुत कुशल बनाते हैं और मुझे लगता है कि मूल रूप से {dtplyr} द्वारा समर्थित नहीं हैं।

अन्य प्रमुख पहलू

क्या / समर्थित नहीं है, यह भी संचालन की जटिलता पर निर्भर करता है और इसमें डेटा-टेबल की मूल विशेषता जैसे अद्यतन-दर-संदर्भ या शामिल है setkey। और क्या अनुवादित कोड अधिक कुशल है (एक है जो data.table उपयोगकर्ता लिखेंगे) एक अन्य कारक भी है (यानी कोड का अनुवाद किया गया है, लेकिन क्या यह कुशल-संस्करण है?)। बहुत सी चीजें आपस में जुड़ी हुई हैं।

इन पहलुओं में से कई ऊपर वर्णित बिंदुओं के साथ अंतर-संबंधित हैं

  • संचालन की जटिलता

  • अद्यतन-दर-संदर्भ

आप पता लगा सकते हैं कि क्या {dtplyr} इन ऑपरेशनों का समर्थन करते हैं, खासकर जब वे संयुक्त होते हैं।

इंटरैक्टिव सत्र के दौरान, छोटे या बड़े डेटासेट के साथ काम करते समय एक और उपयोगी ट्रिक, {data.table} वास्तव में प्रोग्रामिंग को कम करने और समय की जबरदस्त गणना करने के अपने वादे पर खरा उतरता है।

गति और 'सुपरचार्ज्ड रोनेम्स' दोनों के लिए दोहराए जाने वाले चर के लिए कुंजी सेट करना (चर नाम निर्दिष्ट किए बिना सबसेट)।

dt <- data.table(iris)
setkey(dt, Species) 

dt['setosa',    do_something(...), ...]
dt['virginica', do_another(...),   ...]
dt['setosa',    more(...),         ...]

# `by` argument can also be omitted, particularly useful during interactive session
# this ultimately becomes what I call 'naked' syntax, just type what you want to do, without any placeholders. 
# It's simply elegant
dt['setosa', do_something(...), Species, ...]

यदि आपके कार्यों में पहले उदाहरण की तरह केवल सरल शामिल हैं, तो {dtplyr} कार्य प्राप्त कर सकते हैं। जटिल / असमर्थित लोगों के लिए, आप इस गाइड का उपयोग {dtplyr} के अनुवादित लोगों की तुलना करने के लिए कर सकते हैं कि कैसे अनुभवी data.table उपयोगकर्ता डेटा के साथ तेज और मेमोरी कुशल तरीके से कोड करेंगे। अनुवाद का मतलब यह नहीं है कि बड़े डेटा के विभिन्न मामलों से निपटने के लिए अलग-अलग तकनीकें हो सकती हैं। इससे भी अधिक बड़े डेटासेट के लिए, आप {data.able} को {disk.frame} , {fst} और {drake} और अन्य भयानक पैकेजों के साथ मिला सकते हैं ताकि यह सबसे अच्छा हो सके। एक {big.data.table} भी है, लेकिन यह वर्तमान में निष्क्रिय है।

मुझे उम्मीद है कि यह सभी की मदद करेगा। आपका दिन शुभ हो ☺☺


3

नॉन-इक्वि जॉइन और रोलिंग जॉइनिंग का ख्याल आता है। किसी भी योजना में प्रतीत नहीं होता है कि सभी समान कार्यों को dplyr में शामिल करना है इसलिए dtplyr का अनुवाद करने के लिए कुछ भी नहीं है।

वहाँ भी reshaping है (अनुकूलित dcast और reshape2 में एक ही कार्य के बराबर पिघल) कि dplyr में भी नहीं है।

वर्तमान में सभी * _if और * _at फ़ंक्शंस को dtplyr के साथ भी अनुवादित नहीं किया जा सकता है, लेकिन वे कामों में हैं।


0

कुछ में शामिल होने पर एक कॉलम अपडेट करें।

यह अपने आप में एक संपूर्ण पारिस्थितिकी तंत्र है

जिस दिन से मैंने आर शुरू किया है, तब से मुझे कभी सपने में भी ज़रूरत नहीं पड़ी है। क्योंकि डेटाटेबल इतना अच्छा है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.