dplyr

2016-01-31 31 views
6

में एक "अन्य" श्रेणी के साथ top_n से परिणाम कम्बाइन मैं एक डेटा फ्रेम dat1dplyr

Country Count 
1  AUS  1 
2  NZ  2 
3  NZ  1 
4  USA  3 
5  AUS  1 
6  IND  2 
7  AUS  4 
8  USA  2 
9  JPN  5 
10  CN  2 

सबसे पहले मैं प्रति "देश" योग करने के लिए "गणना" चाहते हैं। तो फिर देश के आधार पर शीर्ष 3 कुल मायने रखता है एक अतिरिक्त पंक्ति "अन्य" है, जो ऐसे देश हैं जिनके शीर्ष 3.

प्रत्याशित परिणाम का हिस्सा नहीं हैं का योग है साथ जोड़ा जाना चाहिए इसलिए होगा:

Country Count 
1  AUS  6 
2  JPN  5 
3  USA  5 
4  Others 7 

मैंने नीचे दिए गए कोड को आजमाया है, लेकिन यह नहीं पता कि "अन्य" पंक्ति को कैसे रखा जाए।

dat1 %>% 
    group_by(Country) %>% 
    summarise(Count = sum(Count)) %>% 
    arrange(desc(Count)) %>% 
    top_n(3) 

इस कोड को वर्तमान में देता है:

Country Count 
1  AUS  6 
2  JPN  5 
3  USA  5 

किसी भी मदद की बहुत सराहना की जाएगी। पिछले पंक्तियों का एक सारांश के साथ पहली बार एक क्रमबद्ध data.frame बनाते हैं और फिर rbind शीर्ष तीन पंक्तियों:

dat1 <- structure(list(Country = structure(c(1L, 5L, 5L, 6L, 1L, 3L, 
    1L, 6L, 4L, 2L), .Label = c("AUS", "CN", "IND", "JPN", "NZ", 
    "USA"), class = "factor"), Count = c(1L, 2L, 1L, 3L, 1L, 2L, 
    4L, 2L, 5L, 2L)), .Names = c("Country", "Count"), class = "data.frame",  row.names = c("1", 
    "2", "3", "4", "5", "6", "7", "8", "9", "10")) 
+2

संबंधित प्रश्नोत्तर: ["अन्य" फ़ील्ड बनाना) (http://stackoverflow.com/questions/23730067/creating-an-other-field])। – Henrik

उत्तर

7
top_n के बजाय

का उपयोग कर, इस सुविधा समारोह tally के लिए एक अच्छा मामले की तरह लगता है। यह हुड के नीचे summarise, sum और arrange का उपयोग करता है।

फिर "अन्य" श्रेणी बनाने के लिए factor का उपयोग करें। अंतिम स्तर के रूप में "अन्य" सेट करने के लिए levels तर्क का उपयोग करें। "अन्य" तब तालिका में अंतिम रूप दिया जाएगा (और परिणाम के किसी भी बाद की साजिश में)।

यदि आपके मूल डेटा में "देश" factor है, तो आप Country[1:3]as.character में लपेट सकते हैं।

group_by(df, Country) %>% 
    tally(Count, sort = TRUE) %>% 
    group_by(Country = factor(c(Country[1:3], rep("Other", n() - 3)), 
          levels = c(Country[1:3], "Other"))) %>% 
    tally(n) 

# Country  n 
# (fctr) (int) 
#1  AUS  6 
#2  JPN  5 
#3  USA  5 
#4 Other  7 
3

हम दो चरणों में ऐसा कर सकता है

d <- df %>% group_by(Country) %>% summarise(Count = sum(Count)) %>% arrange(desc(Count)) 

rbind(top_n(d,3), 
     slice(d,4:n()) %>% summarise(Country="other",Count=sum(Count)) 
    ) 

उत्पादन

Country Count 
    (fctr) (int) 
1  AUS  6 
2  JPN  5 
3  USA  5 
4 other  7 
3

यहां data.table का उपयोग कर एक विकल्प है। हम 'data.frame' को 'data.table' (setDT(dat1)) में परिवर्तित करते हैं, जिसे 'देश' द्वारा समूहित किया गया है, 'काउंटर' के sum, फिर order 'गणना' द्वारा, हम rbindlist 'के साथ पहले तीन अवलोकन 'और शेष अवलोकनों की' गणना 'के sum

library(data.table) 
setDT(dat1)[, list(Count=sum(Count)), Country][order(-Count), 
    rbind(.SD[1:3], list(Country='Others', Count=sum(.SD[[2]][4:.N]))) ] 
# Country Count 
#1:  AUS  6 
#2:  USA  5 
#3:  JPN  5 
#4: Others  7 

या base R

d1 <- aggregate(.~Country, dat1, FUN=sum) 
i1 <- order(-d1$Count) 
rbind(d1[i1,][1:3,], data.frame(Country='Others', 
    Count=sum(d1$Count[i1][4:nrow(d1)]))) 
3

आप xtabs() का भी उपयोग कर सकते हैं और परिणाम में हेरफेर कर सकते हैं। यह आधार आर उत्तर है।

s <- sort(xtabs(Count ~ ., dat1), decreasing = TRUE) 
setNames(
    as.data.frame(as.table(c(head(s, 3), Others = sum(tail(s, -3)))), 
    names(dat1) 
) 
# Country Count 
# 1  AUS  6 
# 2  JPN  5 
# 3  USA  5 
# 4 Others  7 
2

एक समारोह कुछ उपयोगी लग सकते:

top_cases = function(v, top, other = 'other'){ 
    cv = class(v) 
    v = as.character(v) 
    v[factor(v, levels = top) %>% is.na()] = other 
    if(cv == 'factor') v = factor(v, levels = c(top, other)) 
    v 
} 

जैसे

> table(state.region) 
state.region 
    Northeast   South North Central   West 
      9   16   12   13 
> top_cases(state.region, c('South','West'), 'North') %>% table() 
. 
South West North 
    16 13 21 

iris %>% mutate(Species = top_cases(Species, c('setosa','versicolor'))) 
0

कुछ एक से अधिक प्रतिशत से मिलकर श्रेणियों प्राप्त करने के लिए इस मामले में रुचि रखने वालों के लिए एक 'अन्य में रखा है। 'श्रेणी, यहां कुछ कोड है।

इसके लिए, 5% से कम कोई भी मूल्य 'अन्य' श्रेणी में जाता है, 'अन्य' श्रेणी का सारांश दिया जाता है, और इसमें 'अन्य' श्रेणी में एकत्रित श्रेणियों की संख्या का एक लेबल शामिल होता है।

othernum <- nrow(sub[(sub$value<.05),]) 
sub<- subset(sub, value >.05) 
toplot <- rbind(sub,c(paste("Other (",othernum," types)", sep=""), 1-sum(sub$value)))