2009-11-02 15 views
207

मान लें कि मेरे पास डेटा के दो कॉलम हैं। पहले में "फर्स्ट", "सेकेंड", "थर्ड" इत्यादि जैसी श्रेणियां होती हैं। दूसरी संख्या में संख्याएं होती हैं जो मैंने "फर्स्ट" की संख्या को दर्शाती हैं।कैसे समूह द्वारा एक चर योग करने के लिए?

उदाहरण के लिए:

Category  Frequency 
First  10 
First  15 
First  5 
Second  2 
Third  14 
Third  20 
Second  3 

मैं श्रेणी के अनुसार डेटा को सॉर्ट और आवृत्ति योग करने के लिए करना चाहते हैं:

Category  Frequency 
First  30 
Second  5 
Third  34 

मैं कैसे आर में यह करना होगा?

उत्तर

234

का उपयोग aggregate:

aggregate(x$Frequency, by=list(Category=x$Category), FUN=sum) 
    Category x 
1 First 30 
2 Second 5 
3 Third 34 

(@thelatemail टिप्पणी embedding), aggregate एक सूत्र इंटरफेस भी

aggregate(Frequency ~ Category, x, sum) 

या यदि आप एकाधिक स्तंभों इकट्ठा करना चाहते हैं, तो आप इस्तेमाल कर सकते हैं है . अंकन

+०१२३६१०५१३८ (भी एक स्तंभ के लिए काम करता है)

या tapply:

tapply(x$Frequency, x$Category, FUN=sum) 
First Second Third 
    30  5  34 

इस डेटा का उपयोग करना:

x <- data.frame(Category=factor(c("First", "First", "First", "Second", 
             "Third", "Third", "Second")), 
        Frequency=c(10,15,5,2,14,20,3)) 
+2

@AndrewMcKinlay, R सांख्यिकी और अन्य कार्यों के लिए, प्रतीकात्मक सूत्रों को परिभाषित करने के लिए tilde का उपयोग करता है। इसे "श्रेणी द्वारा मॉडल फ्रीक्वेंसी" * या * "श्रेणी के आधार पर आवृत्ति" * के रूप में व्याख्या किया जा सकता है।आर में यहां किए गए एक प्रतीकात्मक कार्य को परिभाषित करने के लिए सभी भाषाएं एक विशेष ऑपरेटर का उपयोग नहीं करती हैं। शायद टिल्ड ऑपरेटर की "प्राकृतिक भाषा व्याख्या" के साथ, यह अधिक सार्थक (और यहां तक ​​कि अंतर्ज्ञानी) बन जाता है। मैं व्यक्तिगत रूप से इस प्रतीकात्मक फॉर्मूला प्रतिनिधित्व को अधिक वर्बोज विकल्पों में से कुछ से बेहतर पाता हूं। – r2evans

13

तो x अपने डेटा के साथ एक dataframe है, तो निम्नलिखित तुम क्या चाहते हो जाएगा:

require(doBy) 
summaryBy(Frequency~Category, data=yourdataframe, FUN=sum) 

संपादित करें:

require(reshape) 
recast(x, Category ~ ., fun.aggregate=sum) 
19
library(plyr) 
ddply(tbl, .(Category), summarise, sum = sum(Frequency)) 
15

बस एक तीसरा विकल्प जोड़ने के लिए इस है एक बहुत पुराना जवाब। अब मैं group_by के उपयोग की सलाह दूंगा और ddrr से संक्षेप में, जैसा कि @ डॉकेंडो उत्तर में है।

30

यह कुछ हद तक related to this question है।

तुम भी बस() समारोह से उपयोग कर सकते हैं:

x2 <- by(x$Frequency, x$Category, sum) 
do.call(rbind,as.list(x2)) 

उन अन्य पैकेज (plyr, नयी आकृति प्रदान) एक data.frame लौटने के लाभ है, लेकिन यह द्वारा से परिचित होने के नाते लायक है () क्योंकि यह एक आधार समारोह है।

48

आरसीएस काम करता है द्वारा प्रदान की जवाब और सरल है। हालांकि, अगर आप बड़े डेटासेट से निपटने के लिए और एक प्रदर्शन को बढ़ावा देने की जरूरत है कर रहे हैं वहाँ एक तेजी से वैकल्पिक है:

library(data.table) 
data = data.table(Category=c("First","First","First","Second","Third", "Third", "Second"), 
        Frequency=c(10,15,5,2,14,20,3)) 
data[, sum(Frequency), by = Category] 
# Category V1 
# 1: First 30 
# 2: Second 5 
# 3: Third 34 
system.time(data[, sum(Frequency), by = Category]) 
# user system elapsed 
# 0.008  0.001  0.009 

के एक ही बात करने के लिए डेटा का उपयोग कर कि तुलना करें।फ्रेम और ऊपर से ऊपर:

data = data.frame(Category=c("First","First","First","Second","Third", "Third", "Second"), 
        Frequency=c(10,15,5,2,14,20,3)) 
system.time(aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum)) 
# user system elapsed 
# 0.008  0.000  0.015 

और तुम स्तंभ रखना चाहते हैं इस वाक्य रचना है:

data[,list(Frequency=sum(Frequency)),by=Category] 
# Category Frequency 
# 1: First  30 
# 2: Second   5 
# 3: Third  34 

अंतर कोड के रूप में नीचे को दर्शाता है, बड़े डेटासेट के साथ और अधिक ध्यान देने योग्य हो जाएगा:

data = data.table(Category=rep(c("First", "Second", "Third"), 100000), 
        Frequency=rnorm(100000)) 
system.time(data[,sum(Frequency),by=Category]) 
# user system elapsed 
# 0.055  0.004  0.059 
data = data.frame(Category=rep(c("First", "Second", "Third"), 100000), 
        Frequency=rnorm(100000)) 
system.time(aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum)) 
# user system elapsed 
# 0.287  0.010  0.296 

कई एकत्रित के लिए, आप को जोड़ सकते हैं lapply और +०१२३८८०३६६के रूप में अभी हाल ही में

data[, lapply(.SD, sum), by = Category] 
# Category Frequency 
# 1: First  30 
# 2: Second   5 
# 3: Third  34 
+7

+1 लेकिन 0.296 बनाम 0.05 9 विशेष रूप से प्रभावशाली नहीं है। डेटा आकार को चमकने के लिए डेटाटेबल के लिए 300k पंक्तियों से अधिक और 3 से अधिक समूहों के साथ होना चाहिए। उदाहरण के लिए हम जल्द ही 2 बिलियन से अधिक पंक्तियों का प्रयास करेंगे और समर्थन करेंगे, क्योंकि कुछ डेटाटेबल उपयोगकर्ताओं के पास 250 जीबी रैम है और जीएनयू आर अब लम्बाई> 2^31 का समर्थन करता है। –

+1

सच है। बाहर निकलता है मेरे पास वह सब रैम नहीं है, और बस डेटाटेबल के बेहतर प्रदर्शन के कुछ सबूत प्रदान करने की कोशिश कर रहा था। मुझे यकीन है कि अधिक डेटा के साथ अंतर भी बड़ा होगा। – asieira

+0

मेरे पास 7 मिलियन अवलोकन किए गए थे। 3 सेकंड और कुल() ने ऑपरेशन को पूरा करने के लिए 22 सेकंड का समय लिया। मैं इसे इस विषय पर पोस्ट करने जा रहा था और तुमने मुझे मार दिया! – zazu

114

इस प्रकार, आप भी dplyr पैकेज उस उद्देश्य के लिए उपयोग कर सकते हैं:

library(dplyr) 
x %>% 
    group_by(Category) %>% 
    summarise(Frequency = sum(Frequency)) 

#Source: local data frame [3 x 2] 
# 
# Category Frequency 
#1 First  30 
#2 Second   5 
#3 Third  34 

या, कई सारांश स्तंभों के लिए (भी एक स्तंभ के साथ काम करता है):

x %>% 
    group_by(Category) %>% 
    summarise_each(funs(sum)) 

dplyr के लिए अद्यतन> = 0.5:summarise_eachsummarise_all, summarise_at और dplyr में कार्यों की summarise_if परिवार ने ले लिया है।

या, यदि आप द्वारा समूह के लिए एकाधिक स्तंभों है, आप group_by को कॉमा द्वारा अलग में उन सभी को निर्दिष्ट कर सकते हैं:

mtcars %>% 
    group_by(cyl, gear) %>%       # multiple group columns 
    summarise(max_hp = max(hp), mean_mpg = mean(mpg)) # multiple summary columns 

%>% ऑपरेटर सहित अधिक जानकारी के लिए, introduction to dplyr देखते हैं।

+0

अन्य उत्तरों में प्रस्तुत डेटाटेबल और कुल विकल्पों की तुलना में यह कितनी तेज़ है? – asieira

+2

@asieira, जो सबसे तेज़ है और अंतर कितना बड़ा है (या यदि अंतर ध्यान देने योग्य है) हमेशा आपके डेटा आकार पर निर्भर करेगा। आम तौर पर, बड़े डेटा सेट के लिए, उदाहरण के लिए कुछ जीबी, डेटाटेबल सबसे तेज़ होगा। छोटे डेटा आकार पर, डेटा.table और dplyr अक्सर समूहों की संख्या के आधार पर बंद होते हैं। दोनों डेटा, टेबल और dplyr आधार कार्यों की तुलना में काफी तेज होगा, हालांकि (कुछ परिचालनों के लिए 100-1000 गुना तेज हो सकता है)। यह भी देखें [यहां] (http://stackoverflow.com/questions/21435339/data-table-vs-dplyr-can-one-do-something-well-the-other-cant-or-does-poorly) –

15

कई साल बाद, बस एक और सरल आधार आर समाधान है कि कुछ कारण है xtabs

xtabs(Frequency ~ Category, df) 
# Category 
# First Second Third 
# 30  5  34 

के लिए यहां मौजूद नहीं जोड़ने के लिए या यदि एक data.frame वापस

as.data.frame(xtabs(Frequency ~ Category, df)) 
# Category Freq 
# 1 First 30 
# 2 Second 5 
# 3 Third 34 
14

चाहते रहा है, वहीं हाल ही में आपरेशन के इन प्रकार के अधिकांश के लिए dplyr करने के लिए एक परिवर्तित हो जाते हैं, sqldf पैकेज अभी भी वास्तव में कुछ बातों के लिए अच्छा (और IMHO अधिक पठनीय) है। (ध्यान दें 'Frequency' अब 'value' है)

यहाँ कैसे इस सवाल का sqldf

x <- data.frame(Category=factor(c("First", "First", "First", "Second", 
            "Third", "Third", "Second")), 
       Frequency=c(10,15,5,2,14,20,3)) 

sqldf("select 
      Category 
      ,sum(Frequency) as Frequency 
     from x 
     group by 
      Category") 

## Category Frequency 
## 1 First  30 
## 2 Second   5 
## 3 Third  34 
0

recastcast का उपयोग कर के बजाय साथ जवाब दिया जा सकता का एक उदाहरण है

df <- data.frame(Category = c("First","First","First","Second","Third","Third","Second") 
        , value = c(10,15,5,2,14,20,3)) 

install.packages("reshape") 

result<-cast(df, Category ~ . ,fun.aggregate=sum) 

पाने के लिए:

Category (all) 
First  30 
Second 5 
Third  34 
संबंधित मुद्दे