2013-05-03 8 views
16

संपादित - यह सवाल मूल शीर्षक था < < आर में देगी विस्तृत डेटा >>कंप्यूट मतलब है और एक data.frame में कई चर के लिए समूह द्वारा मानक विचलन


मैं बस चाहता हूँ करने के लिए लंबे समय तक सीखना आर और मेरे जीवन में दूसरों की मदद के लिए इसे लागू करने के तरीके खोजने की कोशिश कर रहा है। एक परीक्षण मामले के रूप में, मैं कुछ डेटा दोबारा बदलने पर काम कर रहा हूं, और मुझे ऑनलाइन मिले उदाहरणों के बाद मुझे परेशानी हो रही है। क्या मैं इस तरह दिखता है के साथ शुरू कर रहा हूँ:

ID Obs 1 Obs 2 Obs 3 
1 43  48  37 
1 27  29  22 
1 36  32  40 
2 33  38  36 
2 29  32  27 
2 32  31  35 
2 25  28  24 
3 45  47  42 
3 38  40  36 

और क्या मैं अंत में इस तरह दिखेगा के साथ हैं:

ID Obs 1 mean Obs 1 std dev Obs 2 mean Obs 2 std dev 
1 x   x    x   x 
2 x   x    x   x 
3 x   x    x   x 

और इसके आगे। मुझे इस बात का अनिश्चितता है कि मुझे अपने लंबे प्रारूप डेटा, या क्या में अतिरिक्त जानकारी चाहिए। मुझे कल्पना है कि गणित का हिस्सा (माध्य और मानक विचलन ढूंढना) आसान हिस्सा होगा, लेकिन मैं उस प्रक्रिया को शुरू करने के लिए सही ढंग से डेटा को दोबारा बदलने के लिए काम करने के लिए काम नहीं कर रहा हूं।

किसी भी मदद के लिए बहुत बहुत धन्यवाद।

+3

बस एक टिप्पणी: मुझे नहीं लगता कि लोगों का आमतौर पर लंबे समय से विस्तृत प्रारूप में जाने से क्या मतलब है। – Frank

+0

बहुत टिप्पणी की है, लेकिन मुझे हैरान है कि इस तरह के एक भ्रामक शीर्षक को ठीक करने की कोई परवाह नहीं है (अब किया गया।) – flodel

उत्तर

15

इसके बारे में जाने के कुछ अलग तरीके हैं। reshape2 एक उपयोगी पैकेज है। व्यक्तिगत रूप से, मैं data.table

नीचे का उपयोग कर की तरह एक कदम-दर-कदम

तो myDF अपने data.frame है:

library(data.table) 
DT <- data.table(myDF) 

DT 

# this will get you your mean and SD's for each column 
DT[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x)))] 

# adding a `by` argument will give you the groupings 
DT[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x))), by=ID] 

# If you would like to round the values: 
DT[, sapply(.SD, function(x) list(mean=round(mean(x), 3), sd=round(sd(x), 3))), by=ID] 

# If we want to add names to the columns 
wide <- setnames(DT[, sapply(.SD, function(x) list(mean=round(mean(x), 3), sd=round(sd(x), 3))), by=ID], c("ID", sapply(names(DT)[-1], paste0, c(".men", ".SD")))) 

wide 

    ID Obs.1.men Obs.1.SD Obs.2.men Obs.2.SD Obs.3.men Obs.3.SD 
1: 1 35.333 8.021 36.333 10.214  33.0 9.644 
2: 2 29.750 3.594 32.250 4.193  30.5 5.916 
3: 3 41.500 4.950 43.500 4.950  39.0 4.243 

इसके अलावा, इस या उपयोगी नहीं हो सकता

> DT[, sapply(.SD, summary), .SDcols=names(DT)[-1]] 
     Obs.1 Obs.2 Obs.3 
Min. 25.00 28.00 22.00 
1st Qu. 29.00 31.00 27.00 
Median 33.00 32.00 36.00 
Mean 34.22 36.11 33.22 
3rd Qu. 38.00 40.00 37.00 
Max. 45.00 48.00 42.00 
17

यहां शायद टी है वह सरल (एक reproducible example के साथ) इसके बारे में जाने का रास्ता:

library(plyr) 
df <- data.frame(ID=rep(1:3, 3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) 
ddply(df, .(ID), summarize, Obs_1_mean=mean(Obs_1), Obs_1_std_dev=sd(Obs_1), 
    Obs_2_mean=mean(Obs_2), Obs_2_std_dev=sd(Obs_2)) 

    ID Obs_1_mean Obs_1_std_dev Obs_2_mean Obs_2_std_dev 
1 1 -0.13994642  0.8258445 -0.15186380  0.4251405 
2 2 1.49982393  0.2282299 0.50816036  0.5812907 
3 3 -0.09269806  0.6115075 -0.01943867  1.3348792 

संपादित करें: निम्न दृष्टिकोण आप लिखने का बहुत बचत होती है जब कई कॉलम के साथ काम कर।

ddply(df, .(ID), colwise(mean)) 

    ID  Obs_1  Obs_2  Obs_3 
1 1 -0.3748831 0.1787371 1.0749142 
2 2 -1.0363973 0.0157575 -0.8826969 
3 3 1.0721708 -1.1339571 -0.5983944 

ddply(df, .(ID), colwise(sd)) 

    ID  Obs_1  Obs_2  Obs_3 
1 1 0.8732498 0.4853133 0.5945867 
2 2 0.2978193 1.0451626 0.5235572 
3 3 0.4796820 0.7563216 1.4404602 
+1

एक और अवलोकन है जिसे आप याद करते हैं। हालांकि यह कम कॉलम के साथ जाने का तरीका है, मुझे लगता है कि यह बहुत जल्दी बदसूरत हो जाता है। – Arun

+0

'विकल्प (चौड़ाई = 300)' – mike

8

यहाँ data.table जवाब पर एक अन्य टेक है, का उपयोग करते हुए कार्सन के डेटा @, कि (क्योंकि lapplysapply के बजाय का उपयोग करने का, और यह भी एक छोटे से तेज) में थोड़ा और अधिक पठनीय है:

library(data.table) 
set.seed(1) 
dt = data.table(ID=c(1:3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) 

dt[, c(mean = lapply(.SD, mean), sd = lapply(.SD, sd)), by = ID] 
# ID mean.Obs_1 mean.Obs_2 mean.Obs_3 sd.Obs_1 sd.Obs_2 sd.Obs_3 
#1: 1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 
#2: 2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 
#3: 3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692 
+0

दूसरे को 'एसडी' का उपयोग करना चाहिए और आप दो बार' एसडी 'का उपयोग करते हैं .. क्या इसके कारण कोई प्रदर्शन समस्या है? कोई उपाय? – Arun

+0

@ अरुण, धन्यवाद, 'एसडी' बिट तय किया गया। मुझे नहीं पता कि उसके कारण प्रदर्शन हिट है या नहीं, मुझे – eddi

+0

@ अरुण दिखता है कि ~ 10% प्रदर्शन हिट है, लेकिन अच्छी खबर यह है कि यह अधिक श्रेणियों के साथ नहीं बढ़ता – eddi

26

यह वह जगह है एक समेकन समस्या, मूल रूप से सुझाए गए प्रश्न के रूप में एक समस्या निवारण समस्या नहीं - हम प्रत्येक कॉलम को आईडी द्वारा एक औसत और मानक विचलन में एकत्र करना चाहते हैं। ऐसे कई पैकेज हैं जो ऐसी समस्याओं को संभालते हैं।

ag <- aggregate(. ~ ID, DF, function(x) c(mean = mean(x), sd = sd(x))) 

नोट 1: एक टिप्पणीकार ने बताया कि ag जिसके लिए कुछ स्तंभ हैं एक डेटा फ्रेम है आर के आधार में यह aggregate इस तरह उपयोग किया जा सकता (यह मानते हुए DF इनपुट डेटा फ्रेम है) मैट्रिक्स। हालांकि शुरुआत में यह अजीब लग सकता है, वास्तव में यह पहुंच को सरल बनाता है। ag में इनपुट DF इनपुट के समान कॉलम हैं।इसका पहला कॉलम ag[[1]]ID और शेष ag[[i+1]] (या समकक्ष ag[-1][[i]]) का ith कॉलम ith इनपुट अवलोकन कॉलम के आंकड़ों का मैट्रिक्स है। यदि कोई ith अवलोकन के जेएच आंकड़े तक पहुंचना चाहता है तो यह ag[[i+1]][, j] है जिसे ag[-1][[i]][, j] के रूप में भी लिखा जा सकता है।

दूसरी तरफ, मान लीजिए कि k इनपुट में प्रत्येक अवलोकन के लिए सांख्यिकीय कॉलम हैं (जहां प्रश्न में 2 = 2)। फिर यदि हम आउटपुट को फ़्लैट करते हैं तो ith अवलोकन कॉलम की जेठ सांख्यिकी तक पहुंचने के लिए हमें अधिक जटिल ag[[k*(i-1)+j+1]] या समकक्ष ag[-1][[k*(i-1)+j]] का उपयोग करना होगा।

उदाहरण के लिए, पहली अभिव्यक्ति की सादगी तुलना बनाम दूसरा:

ag[-1][[2]] 
##  mean  sd 
## [1,] 36.333 10.2144 
## [2,] 32.250 4.1932 
## [3,] 43.500 4.9497 

ag_flat <- do.call("data.frame", ag) # flatten 
ag_flat[-1][, 2 * (2-1) + 1:2] 
## Obs_2.mean Obs_2.sd 
## 1  36.333 10.2144 
## 2  32.250 4.1932 
## 3  43.500 4.9497 

नोट 2: प्रतिलिपि प्रस्तुत करने योग्य रूप में इनपुट है:

Lines <- "ID Obs_1 Obs_2 Obs_3 
1 43  48  37 
1 27  29  22 
1 36  32  40 
2 33  38  36 
2 29  32  27 
2 32  31  35 
2 25  28  24 
3 45  47  42 
3 38  40  36" 
DF <- read.table(text = Lines, header = TRUE) 
+2

शायद यह ध्यान रखना महत्वपूर्ण है: हालांकि, यदि आप संरचना को देखते हैं, तो यह आउटपुट प्रत्येक कॉलम को एकत्रित करने के लिए दो कॉलम के साथ 'डेटा.फ्रेम' दिखाई देगा (परिणामस्वरूप आपके उदाहरण डेटा के साथ 7 कॉलम), आप देखेंगे कि यह वास्तव में केवल चार है कॉलम, समेकित कॉलम * matrices * के साथ। आप इसे 'do.call (data.frame, कुल (। ~ आईडी, डीएफ, फ़ंक्शन (x) सी (माध्य = माध्य (x), sd = sd के साथ ठीक कर सकते हैं (एक्स)))) – A5C1D2H2I1M1N2O1R2T1

+0

@ अंदांडा महतो, अच्छा बिंदु। मैंने कुछ कॉमेट्स को विस्तारित किया है इस। –

6

मैं dplyr समाधान को जोड़ने ।

set.seed(1) 
df <- data.frame(ID=rep(1:3, 3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) 

library(dplyr) 
df %>% group_by(ID) %>% summarise_each(funs(mean, sd)) 

#  ID Obs_1_mean Obs_2_mean Obs_3_mean Obs_1_sd Obs_2_sd Obs_3_sd 
# (int)  (dbl)  (dbl)  (dbl)  (dbl)  (dbl)  (dbl) 
# 1  1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 
# 2  2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 
# 3  3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692 
संबंधित मुद्दे