संपादित करें:
यह उत्तर कितनी अच्छी तरह से मिला, यह देखते हुए, मैंने इसे अब उपलब्ध एक पैकेज विगनेट में परिवर्तित कर दिया है
यह देखते हुए कि यह कितनी बार सामने आता है, मुझे लगता है कि यह वारंट थोड़ा और अधिक विस्तार से है, जोश ओ'ब्रायन द्वारा दिए गए सहायक उत्तर से परे है।
आमतौर पर उद्धृत किया जाता है, जोश द्वारा डी ata के एस ubset के एस के अलावा , मुझे लगता है कि "स्व" या "स्व-संदर्भ" के लिए खड़े होने के लिए "एस" पर विचार करना भी सहायक है - अपने सबसे बुनियादी आधार में है स्वयं के लिए रिफ्लेक्टिव संदर्भ - जैसा कि हम नीचे दिए गए उदाहरणों में देखेंगे, यह विशेष रूप से "क्वेरी" (अर्क / उपसमुच्चय / आदि का उपयोग करके ) को एक साथ जमाने के लिए सहायक है । विशेष रूप से, इसका मतलब यह भी है कि यह खुद एक है (कैवेट के साथ कि यह असाइनमेंट की अनुमति नहीं देता है )।.SD
data.table
[
.SD
data.table
:=
का सबसे सरल उपयोग .SD
कॉलम सब्मिट करने के लिए है (अर्थात, जब .SDcols
निर्दिष्ट किया जाता है); मुझे लगता है कि यह संस्करण समझने में अधिक सरल है, इसलिए हम नीचे पहले कवर करेंगे। .SD
इसके दूसरे उपयोग की व्याख्या , समूहीकरण परिदृश्य (अर्थात, जब by =
या keyby =
निर्दिष्ट किया गया है), थोड़ा अलग है, वैचारिक रूप से (हालांकि मूल रूप में यह एक ही है, क्योंकि, सभी के बाद, एक गैर-समूहित संचालन सिर्फ समूह के साथ एक किनारे का मामला है एक समूह)।
यहाँ कुछ उदाहरण और उदाहरण के कुछ अन्य उदाहरण हैं जो मैं खुद अक्सर लागू करता हूं:
लोडिंग डेटा
डेटा बनाने के बजाय इसे अधिक वास्तविक दुनिया का एहसास देने के लिए, आइए बेसबॉल से कुछ डेटा सेटों को लोड करते हैं Lahman
:
library(data.table)
library(magrittr) # some piping can be beautiful
library(Lahman)
Teams = as.data.table(Teams)
# *I'm selectively suppressing the printed output of tables here*
Teams
Pitching = as.data.table(Pitching)
# subset for conciseness
Pitching = Pitching[ , .(playerID, yearID, teamID, W, L, G, ERA)]
Pitching
नंगा .SD
इस बात का वर्णन करने के लिए कि मैं किस प्रकार के प्रतिवर्तित स्वभाव के बारे में कह रहा हूँ .SD
, इसके सबसे अधिक उपयोग पर विचार करें:
Pitching[ , .SD]
# playerID yearID teamID W L G ERA
# 1: bechtge01 1871 PH1 1 2 3 7.96
# 2: brainas01 1871 WS3 12 15 30 4.50
# 3: fergubo01 1871 NY2 0 0 1 27.00
# 4: fishech01 1871 RC1 4 16 24 4.35
# 5: fleetfr01 1871 NY2 0 1 1 10.00
# ---
# 44959: zastrro01 2016 CHN 1 0 8 1.13
# 44960: zieglbr01 2016 ARI 2 3 36 2.82
# 44961: zieglbr01 2016 BOS 2 4 33 1.52
# 44962: zimmejo02 2016 DET 9 7 19 4.87
# 44963: zychto01 2016 SEA 1 0 12 3.29
यही है, हम अभी लौटे हैं Pitching
, यानी, यह लिखने का एक अत्यधिक क्रियात्मक तरीका था Pitching
या Pitching[]
:
identical(Pitching, Pitching[ , .SD])
# [1] TRUE
.SD
सबसेट के संदर्भ में, अभी भी डेटा का एक सबसेट है, यह सिर्फ एक तुच्छ (सेट स्वयं) है।
कॉलम सबसेटिंग: .SDcols
तर्क का उपयोग करने में निहित स्तंभों.SD
को सीमित करने के लिए क्या है, इसे प्रभावित करने का पहला तरीका है :.SD
.SDcols
[
Pitching[ , .SD, .SDcols = c('W', 'L', 'G')]
# W L G
# 1: 1 2 3
# 2: 12 15 30
# 3: 0 0 1
# 4: 4 16 24
# 5: 0 1 1
# ---
# 44959: 1 0 8
# 44960: 2 3 36
# 44961: 2 4 33
# 44962: 9 7 19
# 44963: 1 0 12
यह सिर्फ दृष्टांत के लिए है और बहुत उबाऊ था। लेकिन यहां तक कि यह केवल उपयोग ही अत्यधिक लाभकारी / सर्वव्यापी डेटा हेरफेर संचालन की एक विस्तृत विविधता के लिए उधार देता है:
स्तंभ प्रकार रूपांतरण
स्तंभ प्रकार रूपांतरण डेटा मूंगिंग के लिए जीवन का एक तथ्य है - इस लेखन के रूप में, fwrite
स्वचालित रूप से Date
या POSIXct
स्तंभों को नहीं पढ़ सकते हैं , और character
/ factor
/ के बीच आगे और पीछे रूपांतरण numeric
आम हैं। हम ऐसे स्तंभों के समूहों को बैच-रूपांतरित .SD
और उपयोग कर सकते .SDcols
हैं।
हम देखते हैं कि निम्नलिखित कॉलम डेटा सेट के रूप character
में संग्रहीत हैं Teams
:
# see ?Teams for explanation; these are various IDs
# used to identify the multitude of teams from
# across the long history of baseball
fkt = c('teamIDBR', 'teamIDlahman45', 'teamIDretro')
# confirm that they're stored as `character`
Teams[ , sapply(.SD, is.character), .SDcols = fkt]
# teamIDBR teamIDlahman45 teamIDretro
# TRUE TRUE TRUE
यदि आप sapply
यहां के उपयोग से भ्रमित हैं, तो ध्यान दें कि यह आधार R के लिए समान है data.frames
:
setDF(Teams) # convert to data.frame for illustration
sapply(Teams[ , fkt], is.character)
# teamIDBR teamIDlahman45 teamIDretro
# TRUE TRUE TRUE
setDT(Teams) # convert back to data.table
इस वाक्यविन्यास को समझने की कुंजी यह है कि यह याद रखना कि एक data.table
(साथ ही data.frame
) को एक list
तत्व के रूप में माना जा सकता है जहां प्रत्येक तत्व एक कॉलम है - इस प्रकार, sapply
/ प्रत्येक कॉलमlapply
पर लागू होता FUN
है और परिणाम के रूप में / आमतौर पर (यहां, रिटर्न देता है) लंबाई 1 है, इसलिए एक वेक्टर लौटाता है)।sapply
lapply
FUN == is.character
logical
sapply
इन स्तंभों को रूपांतरित करने के लिए सिंटैक्स factor
बहुत समान है - बस :=
असाइनमेंट ऑपरेटर जोड़ें
Teams[ , (fkt) := lapply(.SD, factor), .SDcols = fkt]
ध्यान दें कि हमें RHS नाम निर्दिष्ट करने के लिए प्रयास करने के बजाय, इसे स्तंभ नामों के रूप में व्याख्या करने के लिए R को बाध्य करने के लिए fkt
कोष्ठक में लपेटना चाहिए ।()
fkt
का लचीलापन .SDcols
(और :=
) एक स्वीकार करने के लिए character
वेक्टर या एक integer
स्तंभ पदों की वेक्टर भी स्तंभ नाम के पैटर्न के आधार पर रूपांतरण के लिए काम में आ सकता है *। हम सभी factor
कॉलमों को इसमें परिवर्तित कर सकते हैं character
:
fkt_idx = which(sapply(Teams, is.factor))
Teams[ , (fkt_idx) := lapply(.SD, as.character), .SDcols = fkt_idx]
और फिर उन सभी स्तंभों को परिवर्तित करें जिनमें team
वापस शामिल हैं factor
:
team_idx = grep('team', names(Teams), value = TRUE)
Teams[ , (team_idx) := lapply(.SD, factor), .SDcols = team_idx]
** स्पष्ट रूप से कॉलम संख्याओं (जैसे DT[ , (1) := rnorm(.N)]
) का उपयोग करना बुरा व्यवहार है और समय के साथ चुपचाप दूषित कोड को जन्म दे सकता है यदि स्तंभ स्थान बदलते हैं। यहां तक कि अनुमानित संख्याओं का उपयोग करना खतरनाक हो सकता है यदि हम क्रमांकित सूचकांक बनाते समय और जब हम इसका उपयोग करते हैं तो आदेश देने पर स्मार्ट / सख्त नियंत्रण नहीं रखते हैं।
एक मॉडल के आरएचएस को नियंत्रित करना
वैरिंग मॉडल विनिर्देश मजबूत सांख्यिकीय विश्लेषण की एक मुख्य विशेषता है। आइए एक घड़े के ईआरए (अर्जित रन औसत, प्रदर्शन का एक उपाय) की भविष्यवाणी करें और Pitching
तालिका में उपलब्ध कोवरिएट्स के छोटे सेट का उपयोग करें । (रैखिक) संबंध W
(जीत) और ERA
अलग - अलग कैसे होते हैं, इसके आधार पर विनिर्देश में अन्य सहसंयोजक कैसे शामिल होते हैं?
यहाँ एक छोटी लिपि है, .SD
जिसमें इस शक्ति की खोज की गई है:
# this generates a list of the 2^k possible extra variables
# for models of the form ERA ~ G + (...)
extra_var = c('yearID', 'teamID', 'G', 'L')
models =
lapply(0L:length(extra_var), combn, x = extra_var, simplify = FALSE) %>%
unlist(recursive = FALSE)
# here are 16 visually distinct colors, taken from the list of 20 here:
# https://sashat.me/2017/01/11/list-of-20-simple-distinct-colors/
col16 = c('#e6194b', '#3cb44b', '#ffe119', '#0082c8', '#f58231', '#911eb4',
'#46f0f0', '#f032e6', '#d2f53c', '#fabebe', '#008080', '#e6beff',
'#aa6e28', '#fffac8', '#800000', '#aaffc3')
par(oma = c(2, 0, 0, 0))
sapply(models, function(rhs) {
# using ERA ~ . and data = .SD, then varying which
# columns are included in .SD allows us to perform this
# iteration over 16 models succinctly.
# coef(.)['W'] extracts the W coefficient from each model fit
Pitching[ , coef(lm(ERA ~ ., data = .SD))['W'], .SDcols = c('W', rhs)]
}) %>% barplot(names.arg = sapply(models, paste, collapse = '/'),
main = 'Wins Coefficient with Various Covariates',
col = col16, las = 2L, cex.names = .8)
गुणांक में हमेशा अपेक्षित संकेत होता है (बेहतर पिचर्स अधिक जीत और कम रन की अनुमति देते हैं), लेकिन परिमाण काफी हद तक अलग-अलग हो सकते हैं जो हम पर नियंत्रण करते हैं।
सशर्त जुड़ता है
data.table
वाक्य रचना अपनी सादगी और मजबूती के लिए सुंदर है। वाक्यविन्यास x[i]
लचीले रूप से दो सामान्य दृष्टिकोणों को कम करने के लिए संभालता है - जब i
एक logical
वेक्टर होता है, x[i]
तो उन पंक्तियों को वापस कर देगाx
जहां i
है अनुरूपTRUE
; जब i
है एक औरdata.table
, एक join
(सादे रूप में उपयोग किया जाता है key
की रों x
और i
, अन्यथा, जब on =
निर्दिष्ट किया जाता है, उन स्तंभों के मैचों का उपयोग)।
यह सामान्य रूप से बहुत अच्छा है, लेकिन जब हम एक सशर्त प्रदर्शन करने की इच्छा रखते हैं, तो यह कम हो जाता है , जिसमें तालिकाओं के बीच संबंधों की सटीक प्रकृति एक या अधिक स्तंभों में पंक्तियों की कुछ विशेषताओं पर निर्भर करती है।
यह उदाहरण एक विरोधाभास है, लेकिन विचार को दिखाता है; अधिक देखने के लिए यहां ( 1 , 2 ) देखें।
लक्ष्य एक स्तंभ जोड़ने के लिए है team_performance
करने के लिए Pitching
(के रूप में कम से कम 6 दर्ज की गई खेल के साथ घड़ा बीच, सबसे कम युग द्वारा मापा गया) तालिका कि प्रत्येक टीम पर सबसे अच्छा पिचर की टीम के प्रदर्शन (रैंक) रिकॉर्ड करता है।
# to exclude pitchers with exceptional performance in a few games,
# subset first; then define rank of pitchers within their team each year
# (in general, we should put more care into the 'ties.method'
Pitching[G > 5, rank_in_team := frank(ERA), by = .(teamID, yearID)]
Pitching[rank_in_team == 1, team_performance :=
# this should work without needing copy();
# that it doesn't appears to be a bug:
# https://github.com/Rdatatable/data.table/issues/1926
Teams[copy(.SD), Rank, .(teamID, yearID)]]
ध्यान दें कि x[y]
सिंटैक्स nrow(y)
मान लौटाता है, यही कारण है कि इस मामले में आरएचएस के बाद से .SD
दाईं ओर है Teams[.SD]
( मान के :=
लिए nrow(Pitching[rank_in_team == 1])
मूल्यों की आवश्यकता है)।
समूह .SD
संचालन
अक्सर, हम समूह स्तर पर अपने डेटा पर कुछ ऑपरेशन करना चाहते हैं । जब हम निर्दिष्ट by =
(या keyby =
) करते हैं, तो क्या होता है के लिए मानसिक मॉडल जब data.table
प्रक्रियाओं को कई घटक उप में विभाजित होने के रूप j
में आपके बारे में सोचना होता data.table
है-data.table
है, जो मेल खाती है में से प्रत्येक के अपने की एक एकल मूल्य को by
चर (ओं):
इस मामले में, .SD
प्रकृति में एक से अधिक है - यह इनमें से प्रत्येक उप- data.table
एस को संदर्भित करता है , एक-एक-बार (थोड़ा अधिक सटीक, गुंजाइश).SD
एक एकल उप- है data.table
)। यह हमें एक ऑपरेशन को संक्षिप्त रूप से व्यक्त करने की अनुमति देता है जिसे हम प्रत्येक उपdata.table
पर प्रदर्शन करना चाहते हैं- इससे पहले कि पुन: इकट्ठे परिणाम हमारे पास वापस आ जाए।
यह विभिन्न सेटिंग्स में उपयोगी है, जिनमें से सबसे आम यहां प्रस्तुत किए गए हैं:
समूह उपशमन
चलो लाहमान डेटा में प्रत्येक टीम के लिए डेटा का सबसे हालिया सीज़न मिलता है। यह काफी सरलता से किया जा सकता है:
# the data is already sorted by year; if it weren't
# we could do Teams[order(yearID), .SD[.N], by = teamID]
Teams[ , .SD[.N], by = teamID]
स्मरण करो जो .SD
स्वयं एक है data.table
, और जो .N
एक समूह में कुल पंक्तियों की संख्या को संदर्भित करता है (यह nrow(.SD)
प्रत्येक समूह के भीतर बराबर है ), इसलिए प्रत्येक के साथ जुड़ी अंतिम पंक्ति के लिए संपूर्णता.SD[.N]
देता है ।.SD
teamID
इसका एक और सामान्य संस्करण प्रत्येक समूह के लिए पहला अवलोकन .SD[1L]
प्राप्त करने के बजाय उपयोग करना है ।
समूह ऑप्टिमा
मान लें कि हम प्रत्येक टीम के लिए सर्वश्रेष्ठ वर्ष लौटना चाहते थे , जैसा कि उनके कुल रन रन की संख्या से मापा जाता है ( R
हम आसानी से इसे अन्य मैट्रिक्स के संदर्भ में समायोजित कर सकते हैं)। प्रत्येक उप से एक निश्चित तत्व लेने के बजाय data.table
, हम अब वांछित सूचकांक को गतिशील रूप से परिभाषित करते हैं:
Teams[ , .SD[which.max(R)], by = teamID]
ध्यान दें कि इस दृष्टिकोण को निश्चित रूप से प्रत्येक के .SDcols
केवल भागों को वापस करने के लिए जोड़ा जा सकता है ( विभिन्न उपसमूह में तय किए जाने वाले कैविएट के साथ )data.table
.SD
.SDcols
NB : .SD[1L]
वर्तमान में GForce
( यह भी देखें ) द्वारा अनुकूलित किया गया है , data.table
आंतरिक जो बड़े पैमाने पर सबसे आम समूहीकृत संचालन को गति देता है जैसे - sum
या अधिक विवरण देखें और इस मोर्चे पर अपडेट के लिए सुविधा सुधार अनुरोधों के लिए / वॉयस समर्थन पर नज़र रखें: 1 , 2 , 3 , 4 , 5 ,mean
?GForce
6
ग्रुपेड रिग्रेशन
बीच के संबंध में पूछताछ में लौटकर ERA
और W
, मान लें कि हम इस रिश्ते को टीम द्वारा अलग करने की उम्मीद करते हैं (यानी, प्रत्येक टीम के लिए अलग ढलान है)। हम इस संबंध में आसानी से इस संबंध में विविधता का पता लगाने के लिए इस प्रतिगमन को फिर से चला सकते हैं (इस दृष्टिकोण से मानक त्रुटियां आम तौर पर गलत हैं - विनिर्देश ERA ~ W*teamID
बेहतर होगा - यह दृष्टिकोण पढ़ने में आसान है और गुणांक ठीक हैं) :
# use the .N > 20 filter to exclude teams with few observations
Pitching[ , if (.N > 20) .(w_coef = coef(lm(ERA ~ W))['W']), by = teamID
][ , hist(w_coef, 20, xlab = 'Fitted Coefficient on W',
ylab = 'Number of Teams', col = 'darkgreen',
main = 'Distribution of Team-Level Win Coefficients on ERA')]
हालांकि, निष्पक्षता की एक उचित मात्रा है, वहाँ मनाया समग्र मूल्य के आसपास एक अलग एकाग्रता है
उम्मीद है कि इसने .SD
सुंदर, कुशल कोड को सुविधाजनक बनाने की शक्ति को स्पष्ट कर दिया है data.table
!
?data.table
v1.7.10 में सुधार किया गया था, इस सवाल के लिए धन्यवाद। यह अब.SD
स्वीकृत उत्तर के अनुसार नाम की व्याख्या करता है ।