data.table
रेज़ैपिंग, स्टैकिंग और विभाजन
खोज…
टिप्पणियों
आधिकारिक विगनेट , "डेटाटेबल्स का उपयोग करके कुशल फेरबदल" , इस विषय का सबसे अच्छा परिचय है।
कई रिशेपिंग कार्यों को लंबे और चौड़े स्वरूपों के बीच चलने की आवश्यकता होती है:
- वाइड डेटा एक अलग चर का प्रतिनिधित्व करने वाले प्रत्येक स्तंभ के साथ डेटा है, और अलग-अलग टिप्पणियों का प्रतिनिधित्व करने वाली पंक्तियों
- फॉर्म आईडी के साथ लंबा डाटा होता है चर | मान, जहां प्रत्येक पंक्ति अवलोकन-चर जोड़ी का प्रतिनिधित्व करती है
data.table के साथ पिघलें और कास्ट करें
data.table
आपके डेटा को कुशलतापूर्वक और आसानी से फिर से साझा करने के लिए संभावनाओं की एक विस्तृत श्रृंखला प्रदान करता है
उदाहरण के लिए, लंबे समय से विस्तृत करने के लिए देगी, जबकि आप दोनों कई चर में पारित कर सकते हैं value.var
और में fun.aggregate
एक ही समय में मानकों
library(data.table) #v>=1.9.6
DT <- data.table(mtcars)
लंबा चौड़ा
dcast(DT, gear ~ cyl, value.var = c("disp", "hp"), fun = list(mean, sum))
gear disp_mean_4 disp_mean_6 disp_mean_8 hp_mean_4 hp_mean_6 hp_mean_8 disp_sum_4 disp_sum_6 disp_sum_8 hp_sum_4 hp_sum_6 hp_sum_8
1: 3 120.100 241.5 357.6167 97 107.5 194.1667 120.1 483.0 4291.4 97 215 2330
2: 4 102.625 163.8 NaN 76 116.5 NaN 821.0 655.2 0.0 608 466 0
3: 5 107.700 145.0 326.0000 102 175.0 299.5000 215.4 145.0 652.0 204 175 599
यह gear
को इंडेक्स कॉलम के रूप में सेट करेगा, जबकि mean
और sum
की गणना हर gear
और cyl
संयोजन के लिए disp
और hp
लिए की जाएगी। मामले में कुछ संयोजनों आप इस तरह के रूप में अतिरिक्त पैरामीटर निर्दिष्ट कर सकते हैं मौजूद नहीं है na.rm = TRUE
(जो करने के लिए पारित हो जाएगा mean
और sum
कार्यों) या निर्मित निर्दिष्ट fill
तर्क। आप मार्जिन भी जोड़ सकते हैं, लापता संयोजनों को छोड़ सकते हैं और डेटा को कम कर सकते हैं। और देखें ?data.table::dcast
चौड़ी से लंबी
विस्तृत से लंबे समय तक measure.vars
करते हुए, आप कॉलम को पास कर सकते हैं। उदाहरण के लिए, नियमित अभिव्यक्ति का उपयोग करते हुए पैरामीटर
print(melt(DT, c("cyl", "gear"), measure = patterns("^d", "e")), n = 10)
cyl gear variable value1 value2
1: 6 4 1 160.00 16.46
2: 6 4 1 160.00 17.02
3: 4 4 1 108.00 18.61
4: 6 3 1 258.00 19.44
5: 8 3 1 360.00 17.02
---
60: 4 5 2 3.77 5.00
61: 8 5 2 4.22 5.00
62: 6 5 2 3.62 5.00
63: 8 5 2 3.54 5.00
64: 4 4 2 4.11 4.00
यह होगा melt
द्वारा डेटा cyl
और gear
सूचकांक स्तंभों के रूप में है, जबकि चर के साथ शुरू करने के लिए सभी मूल्यों d
( disp
और drat
) में मौजूद रहेंगे value1
और चर कि अक्षर होना के लिए मूल्यों e
उन में ( qsec
और gear
) value2
कॉलम में मौजूद होगा।
आप यह भी निर्दिष्ट करने, जबकि परिणाम में सभी कॉलम नामों में नाम बदल सकते हैं variable.name
और value.name
बहस या अगर आप चाहते हैं तय character
कॉलम स्वचालित रूप से करने के लिए परिवर्तित किया factor
या नहीं, जबकि निर्दिष्ट करने variable.factor
और value.factor
तर्क। अधिक देखें ?data.table::melt
`Data.table` का उपयोग करके रीसेट करें
data.table
reshape2
के melt
और dcast
कार्यों को dcast
है
( संदर्भ: Data.tables का उपयोग करके कुशल पुन: आकार देना )
library(data.table)
## generate some data
dt <- data.table(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dt
# name numbers value
# 1: firstName 1 -0.8551881
# 2: firstName 2 -1.0561946
# 3: firstName 3 0.2671833
# 4: firstName 4 1.0662379
# 5: secondName 1 -0.4771341
# 6: secondName 2 1.2830651
# 7: secondName 3 -0.6989682
# 8: secondName 4 -0.6592184
लंबा चौड़ा
dcast(data = dt,
formula = name ~ numbers,
value.var = "value")
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
कई स्तंभों पर ( data.table
के data.table
1.9.6)
## add an extra column
dt[, value2 := value * 2]
## cast multiple value columns
dcast(data = dt,
formula = name ~ numbers,
value.var = c("value", "value2"))
# name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
वाइड टू लॉन्ग
## use a wide data.table
dt <- fread("name 1 2 3 4
firstName 0.1836433 -0.8356286 1.5952808 0.3295078
secondName -0.8204684 0.4874291 0.7383247 0.5757814", header = T)
dt
# name 1 2 3 4
# 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078
# 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
## melt to long, specifying the id column, and the name of the columns
## in the resulting long data.table
melt(dt,
id.vars = "name",
variable.name = "numbers",
value.name = "myValue")
# name numbers myValue
# 1: firstName 1 0.1836433
# 2: secondName 1 -0.8204684
# 3: firstName 2 -0.8356286
# 4: secondName 2 0.4874291
# 5: firstName 3 1.5952808
# 6: secondName 3 0.7383247
# 7: firstName 4 0.3295078
# 8: secondName 4 0.5757814
पिघल का उपयोग कर व्यापक से लंबे प्रारूप में जा रहे हैं
पिघलना: मूल बातें
मेल्टिंग का उपयोग डेटा को विस्तृत से लंबे प्रारूप में बदलने के लिए किया जाता है।
एक विस्तृत डेटा सेट के साथ शुरू:
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = 7:9)
Data.table में melt
फंक्शन का उपयोग करके हम अपने डेटा को पिघला सकते हैं। यह लंबे प्रारूप में एक और डेटा देता है।
melt(DT, id.vars = c("ID","Age"))
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
class(melt(DT, id.vars = c("ID","Age")))
# "data.table" "data.frame"
id.vars
पैरामीटर में सेट किए गए किसी भी कॉलम को चर नहीं माना जाता है। वैकल्पिक रूप से, हम इन measure.vars
का उपयोग करके स्पष्ट रूप से सेट कर सकते हैं। तर्क तर्क:
melt(DT, measure.vars = c("OB_A","OB_B","OB_C"))
ID Age variable value
1: a 20 OB_A 1
2: b 21 OB_A 2
3: c 22 OB_A 3
4: a 20 OB_B 4
5: b 21 OB_B 5
6: c 22 OB_B 6
7: a 20 OB_C 7
8: b 21 OB_C 8
9: c 22 OB_C 9
इस स्थिति में, कोई भी स्तंभ जो measure.vars
में सेट नहीं किए जाते हैं। उन्हें आईडी माना जाता है।
यदि हम दोनों को स्पष्ट रूप से सेट करते हैं, तो यह केवल चयनित कॉलम लौटाएगा:
melt(DT, id.vars = "ID", measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
परिणाम में नामकरण चर और मान
हम variable.name
और value.name
का उपयोग करके दी गई तालिका के कॉलम नामों में हेरफेर कर सकते हैं
melt(DT,
id.vars = c("ID"),
measure.vars = c("OB_C"),
variable.name = "Test",
value.name = "Result"
)
ID Test Result
1: a OB_C 7
2: b OB_C 8
3: c OB_C 9
परिणाम में माप चर के लिए प्रकार सेट करना
डिफ़ॉल्ट रूप से, एक data.table धर्मान्तरित सभी पिघलने measure.vars
कारकों को:
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT[, variable])
# "factor"
इसके बजाय वर्ण के रूप में सेट करने के लिए, variable.factor
तर्क का उपयोग करें:
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), variable.factor = FALSE)
class(M_DT[, variable])
# "character"
मान आमतौर पर मूल स्तंभ के डेटा प्रकार से प्राप्त होते हैं:
class(DT[, value])
# "integer"
class(M_DT[, value])
# "integer"
यदि कोई विरोधाभास है, तो डेटा प्रकारों का उपयोग किया जाएगा। उदाहरण के लिए:
M_DT <- melt(DT,id.vars = c("Age"), measure.vars = c("ID","OB_C"))
class(M_DT[, value])
# "character"
पिघलते समय, कोई भी कारक चर चरित्र प्रकार के लिए मजबूर किया जाएगा:
DT[, OB_C := factor(OB_C)]
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
class(M_DT)
# "character"
इससे बचने के लिए और शुरुआती टाइपिंग को संरक्षित करने के लिए, value.factor
तर्क का उपयोग करें:
M_DT <- melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), value.factor = TRUE)
class(M_DT)
# "factor"
लापता मूल्यों को संभालना
डिफ़ॉल्ट रूप से, किसी भी NA
मान को पिघले हुए डेटा में संरक्षित किया जाता है
DT = data.table(ID = letters[1:3], Age = 20:22, OB_A = 1:3, OB_B = 4:6, OB_C = c(7:8,NA))
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"))
ID variable value
1: a OB_C 7
2: b OB_C 8
3: c OB_C NA
यदि इन्हें आपके डेटा से हटा दिया जाए, तो na.rm = TRUE
सेट करें
melt(DT,id.vars = c("ID"), measure.vars = c("OB_C"), na.rm = TRUE)
ID variable value
1: a OB_C 7
2: b OB_C 8
Dcast का उपयोग करके लंबे से चौड़े प्रारूप में जा रहे हैं
कास्टिंग: मूल बातें
लंबे समय से विस्तृत प्रारूप में डेटा को बदलने के लिए कास्टिंग का उपयोग किया जाता है।
एक लंबे डेटा सेट के साथ शुरू:
DT = data.table(ID = rep(letters[1:3],3), Age = rep(20:22,3), Test = rep(c("OB_A","OB_B","OB_C"), each = 3), Result = 1:9)
हम dcast
में dcast
फ़ंक्शन का उपयोग करके अपना डेटा डाल सकते हैं। यह विस्तृत प्रारूप में एक और डेटा देता है।
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
class(dcast(DT, formula = ID ~ Test, value.var = "Result"))
[1] "data.table" "data.frame"
एक मूल्य कास्टिंग
उचित कलाकारों के लिए एक value.var
तर्क आवश्यक है - यदि प्रदान नहीं किया गया है तो dcast आपके डेटा के आधार पर एक धारणा बना देगा।
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
ID OB_A OB_B OB_C
1: a 20 20 20
2: b 21 21 21
3: c 22 22 22
एक सूची में एकाधिक value.var
s प्रदान किया जा सकता है
dcast(DT, formula = ID ~ Test, value.var = list("Result","Age"))
ID Result_OB_A Result_OB_B Result_OB_C Age_OB_A Age_OB_B Age_OB_C
1: a 1 4 7 20 20 20
2: b 2 5 8 21 21 21
3: c 3 6 9 22 22 22
सूत्र
dcast
में फार्मूला तर्क का उपयोग करके कास्टिंग को नियंत्रित किया dcast
। यह फॉर्म ROWS ~ COLUMNS का है
dcast(DT, formula = ID ~ Test, value.var = "Result")
ID OB_A OB_B OB_C
1: a 1 4 7
2: b 2 5 8
3: c 3 6 9
dcast(DT, formula = Test ~ ID, value.var = "Result")
Test a b c
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
+
का उपयोग करके दोनों चर और स्तंभों को और अधिक चर के साथ विस्तारित किया जा सकता है
dcast(DT, formula = ID + Age ~ Test, value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
dcast(DT, formula = ID ~ Age + Test, value.var = "Result")
ID 20_OB_A 20_OB_B 20_OB_C 21_OB_A 21_OB_B 21_OB_C 22_OB_A 22_OB_B 22_OB_C
1: a 1 4 7 NA NA NA NA NA NA
2: b NA NA NA 2 5 8 NA NA NA
3: c NA NA NA NA NA NA 3 6 9
#order is important
dcast(DT, formula = ID ~ Test + Age, value.var = "Result")
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 NA NA 4 NA NA 7 NA NA
2: b NA 2 NA NA 5 NA NA 8 NA
3: c NA NA 3 NA NA 6 NA NA 9
कास्टिंग अक्सर उन कोशिकाओं को बना सकता है जहां डेटा में कोई अवलोकन मौजूद नहीं है। डिफ़ॉल्ट रूप से यह NA
द्वारा दर्शाया गया है, जैसा कि ऊपर दिया गया है। हम इसे fill=
तर्क के साथ ओवरराइड कर सकते हैं।
dcast(DT, formula = ID ~ Test + Age, value.var = "Result", fill = 0)
ID OB_A_20 OB_A_21 OB_A_22 OB_B_20 OB_B_21 OB_B_22 OB_C_20 OB_C_21 OB_C_22
1: a 1 0 0 4 0 0 7 0 0
2: b 0 2 0 0 5 0 0 8 0
3: c 0 0 3 0 0 6 0 0 9
आप फॉर्मूला ऑब्जेक्ट में दो विशेष चर का भी उपयोग कर सकते हैं
-
.
कोई अन्य चर का प्रतिनिधित्व नहीं करता है -
...
अन्य सभी चर का प्रतिनिधित्व करता है
dcast(DT, formula = Age ~ ., value.var = "Result")
Age .
1: 20 3
2: 21 3
3: 22 3
dcast(DT, formula = ID + Age ~ ..., value.var = "Result")
ID Age OB_A OB_B OB_C
1: a 20 1 4 7
2: b 21 2 5 8
3: c 22 3 6 9
हमारे मूल्य को एकत्र करना
हम एक चरण में मूल्यों को भी जोड़ और एकत्र कर सकते हैं। इस मामले में, हमारे पास आयु और आईडी के प्रत्येक चौराहे पर तीन अवलोकन हैं। यह निर्धारित करने के लिए कि हम क्या एकत्रीकरण चाहते हैं, हम fun.aggregate
तर्क का उपयोग करते हैं:
#length
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = length)
ID 20 21 22
1: a 3 0 0
2: b 0 3 0
3: c 0 0 3
#sum
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = sum)
ID 20 21 22
1: a 12 0 0
2: b 0 15 0
3: c 0 0 18
#concatenate
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = function(x){paste(x,collapse = "_")})
ID 20 21 22
1: a 1_4_7
2: b 2_5_8
3: c 3_6_9
हम कई कार्यों का उपयोग करने के लिए fun.aggregate
लिए एक सूची भी पास कर सकते हैं
dcast(DT, formula = ID ~ Age, value.var = "Result", fun.aggregate = list(sum,length))
ID Result_sum_20 Result_sum_21 Result_sum_22 Result_length_20 Result_length_21 Result_length_22
1: a 12 0 0 3 0 0
2: b 0 15 0 0 3 0
3: c 0 0 18 0 0 3
यदि हम एक से अधिक फ़ंक्शन और एक से अधिक मान पास करते हैं, तो हम value.vars के वेक्टर को पास करके सभी संयोजनों की गणना कर सकते हैं
dcast(DT, formula = ID ~ Age, value.var = c("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_function_20 Test_function_21 Test_function_22 Result_length_20 Result_length_21
1: a 1_4_7 OB_A_OB_B_OB_C 3 0
2: b 2_5_8 OB_A_OB_B_OB_C 0 3
3: c 3_6_9 OB_A_OB_B_OB_C 0 0
Result_length_22 Test_length_20 Test_length_21 Test_length_22
1: 0 3 0 0
2: 0 0 3 0
3: 3 0 0 3
जहां प्रत्येक जोड़ी की गणना value1_formula1, value1_formula2, ... , valueN_formula(N-1), valueN_formulaN
।
वैकल्पिक रूप से, हम एक सूची के रूप में 'value.var' पास करके एक-से-एक करके अपने मूल्यों और कार्यों का मूल्यांकन कर सकते हैं:
dcast(DT, formula = ID ~ Age, value.var = list("Result","Test"), fun.aggregate = list(function(x){paste0(x,collapse = "_")},length))
ID Result_function_20 Result_function_21 Result_function_22 Test_length_20 Test_length_21 Test_length_22
1: a 1_4_7 3 0 0
2: b 2_5_8 0 3 0
3: c 3_6_9 0 0 3
परिणाम में नामकरण कॉलम
डिफ़ॉल्ट रूप से, स्तंभ नाम घटक अंडरस्कोर _
द्वारा अलग किए जाते हैं। इसे sep=
तर्क का उपयोग करके मैन्युअल रूप से ओवरराइड किया जा सकता है:
dcast(DT, formula = Test ~ ID + Age, value.var = "Result")
Test a_20 b_21 c_22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", sep = ",")
Test a,20 b,21 c,22
1: OB_A 1 2 3
2: OB_B 4 5 6
3: OB_C 7 8 9
यह किसी भी अलग होगा fun.aggregate
या value.var
हम का उपयोग करें:
dcast(DT, formula = Test ~ ID + Age, value.var = "Result", fun.aggregate = c(sum,length), sep = ",")
Test Result,sum,a,20 Result,sum,b,21 Result,sum,c,22 Result,length,a,20 Result,length,b,21 Result,length,c,22
1: OB_A 1 2 3 1 1 1
2: OB_B 4 5 6 1 1 1
3: OB_C 7 8 9 1 1 1
Rbindlist का उपयोग करके कई टेबल को स्टैक करना
R में एक आम खराबी इन लाइनों के साथ जाती है:
आपके पास
DT1
,DT2
, ...,DT11
जैसे नामों के साथ संबंधित तालिकाओं का एक गुच्छा नहीं होना चाहिए। नाम से ऑब्जेक्ट्स को पढ़ने और असाइन करने की पूरी तरह से गड़बड़ है। समाधान डेटा की तालिकाओं की एक सूची है!
ऐसी सूची दिखती है
set.seed(1)
DT_list = lapply(setNames(1:3, paste0("D", 1:3)), function(i)
data.table(id = 1:2, v = sample(letters, 2)))
$D1
id v
1: 1 g
2: 2 j
$D2
id v
1: 1 o
2: 2 w
$D3
id v
1: 1 f
2: 2 w
एक और परिप्रेक्ष्य यह है कि आपको इन तालिकाओं को एक तालिका के रूप में संग्रहीत करना चाहिए, उन्हें स्टैक करके। यह rbindlist
का उपयोग करने के लिए सीधा है:
DT = rbindlist(DT_list, id="src")
src id v
1: D1 1 g
2: D1 2 j
3: D2 1 o
4: D2 2 w
5: D3 1 f
6: D3 2 w
यह प्रारूप data.table सिंटैक्स के साथ बहुत अधिक समझ में आता है, जहां "समूह द्वारा" ऑपरेशन सामान्य और सीधे हैं।
एक गहरी नज़र के लिए, ग्रेगर का जवाब शुरू करने के लिए एक अच्छी जगह हो सकती है। इसके अलावा बाहर की जाँच करें ?rbindlist
CSV से तालिकाओं के एक समूह में पढ़ने और फिर उन्हें स्टैक करने का एक अलग उदाहरण है ।