2013-08-28 7 views
9

मैं अपने डेटा के साथ काउंटर बनाएं कि लग रहा है नीचे की तरह:कई चर

CustomerID TripDate TripCounter 
1   1/3/2013 1 
1   1/4/2013 2 
1   1/9/2013 3 
2   2/1/2013 1 
2   2/4/2013 2 
3   1/2/2013 1 

Tripcounter प्रत्येक के लिए होगा:

CustomerID TripDate 
1   1/3/2013 
1   1/4/2013 
1   1/9/2013 
2   2/1/2013 
2   2/4/2013 
3   1/2/2013 

मैं एक काउंटर चर, जो नीचे तरह होगा बनाने की जरूरत ग्राहक।

उत्तर

12

ave का उपयोग करें। अपने data.frame कहा जाता है "mydf" यह मानते हुए:

mydf$counter <- with(mydf, ave(CustomerID, CustomerID, FUN = seq_along)) 
mydf 
# CustomerID TripDate counter 
# 1   1 1/3/2013  1 
# 2   1 1/4/2013  2 
# 3   1 1/9/2013  3 
# 4   2 2/1/2013  1 
# 5   2 2/4/2013  2 
# 6   3 1/2/2013  1 

क्या इसके लायक है के लिए, मैं भी कार्यान्वित एक समारोह में इस दृष्टिकोण का एक संस्करण मेरी "splitstackshape" पैकेज में शामिल। समारोह getanID कहा जाता है:

mydf <- data.frame(IDA = c("a", "a", "a", "b", "b", "b", "b"), 
        IDB = c(1, 2, 1, 1, 2, 2, 2), values = 1:7) 
mydf 
# install.packages("splitstackshape") 
library(splitstackshape) 
# getanID(mydf, id.vars = c("IDA", "IDB")) 
getanID(mydf, id.vars = 1:2) 
# IDA IDB values .id 
# 1 a 1  1 1 
# 2 a 2  2 1 
# 3 a 1  3 2 
# 4 b 1  4 1 
# 5 b 2  5 1 
# 6 b 2  6 2 
# 7 b 2  7 3 

आप ऊपर के उदाहरण से देख सकते हैं, मैं इस तरह से है कि आप एक या अधिक स्तंभ है कि आईडी स्तंभ के रूप में व्यवहार किया जाना चाहिए निर्दिष्ट कर सकते हैं में समारोह लिखा है। यह देखने के लिए जांच करता है कि id.vars में से कोई भी डुप्लीकेट किया गया है, और यदि वे हैं, तो यह आपके लिए एक नया आईडी चर उत्पन्न करता है।

+0

धन्यवाद बहुत आनंद! यह काम करता है! – kaos1511

0

यहां प्रक्रिया स्टाइल कोड है। मैं तुम्हें आर में पाश उपयोग कर रहे हैं तो आप शायद कुछ गलत

x <- dataframe$CustomerID 
dataframe$counter <- 0 
y <- dataframe$counter 
count <- 1 
for (i in 1:length(x)) { 
    ifelse (x[i] == x[i-1], count <- count + 1, count <- 1) 
    y[i] <- count 
} 
dataframe$counter <- y 
+1

शायद आप कुछ गलत नहीं कर रहे हैं, लेकिन निश्चित रूप से आप कुछ धीमा कर रहे होंगे। – juba

+1

और मैं कोड के 9 लाइनों पर @AnandaMahto के एक-लाइनर को पसंद करूंगा। –

+1

बाहर निकलता है, मैं भी एक लाइनर पसंद करता हूं और मैं निश्चित रूप से मेरी धीमी गति को देखने के लिए बेंचमार्क करता हूं –

2

मैं अक्सर ऐसा करने की जरूरत है क्या कर रहे हैं जैसी चीजों में विश्वास करते हैं, और एक समारोह है कि यह पिछले जवाब की तुलना में अलग सिद्ध लिखा था न। मुझे यकीन नहीं है कि कौन सा समाधान सबसे कुशल है।

idCounter <- function(x) { 
    unlist(lapply(rle(x)$lengths, seq_len)) 
} 

mydf$TripCounter <- idCounter(mydf$CustomerID) 
+0

यह गलत है। आप 'अनुक्रम' का उपयोग करना चाहते थे जो 'seq_along' से * बहुत अलग * है। – A5C1D2H2I1M1N2O1R2T1

+0

इसके बजाय इसे आज़माएं: 'idCounter <- फ़ंक्शन (x) अनुक्रम (राल (x) $ लंबाई)' – A5C1D2H2I1M1N2O1R2T1

+0

@Ananda, इसे पकड़ने के लिए धन्यवाद, मैंने गलती से "seq_len" (अब ऊपर तय) के बजाय "seq_along" टाइप किया है। मैं 'अनुक्रम' से अपरिचित था, और 'अनुक्रम' को देख रहा था, मुझे लगता है कि मेरी फ़ंक्शन परिभाषा 'अनुक्रम' (यानी, अनुक्रम <- फ़ंक्शन (एनवीसीसी) असूची (समान रूप से (nvec, seq_len)) के समान है।), सिवाय इसके कि मैंने 'nvec' को 'rle (x) $ lengths' से बदल दिया है। 'अनुक्रम' का उपयोग करना निश्चित रूप से अधिक सुरुचिपूर्ण है; हालांकि, अपेक्षाकृत नए आर उपयोगकर्ता होने के नाते, मुझे अपना लंबा संस्करण उपयोगी लगता है क्योंकि मैं शामिल चरणों का बेहतर पालन कर सकता हूं। – RayB

7

आप भी इस के लिए plyr (का उपयोग करते हुए @ AnadaMahto के उदाहरण डेटा) का उपयोग कर सकते हैं: होने के लिए

> ddply(mydf, .(IDA, IDB), transform, .id = seq_along(IDA)) 
    IDA IDB values .id 
1 a 1  1 1 
2 a 1  3 2 
3 a 2  2 1 
4 b 1  4 1 
5 b 2  5 1 
6 b 2  6 2 
7 b 2  7 3 

ध्यान दें कि plyr एक प्रतिष्ठा है नहीं करता है:

> ddply(mydf, .(IDA), transform, .id = seq_along(IDA)) 
    IDA IDB values .id 
1 a 1  1 1 
2 a 2  2 2 
3 a 1  3 3 
4 b 1  4 1 
5 b 2  5 2 
6 b 2  6 3 
7 b 2  7 4 

या यहाँ तक कि सबसे तेज़ समाधान, इसके लिए आपको data.table पर एक नज़र डालने की आवश्यकता है।

library(data.table) 
DT <- data.table(mydf) 
DT[, .id := sequence(.N), by = "IDA,IDB"] 
DT 
# IDA IDB values .id 
# 1: a 1  1 1 
# 2: a 2  2 1 
# 3: a 1  3 2 
# 4: b 1  4 1 
# 5: b 2  5 1 
# 6: b 2  6 2 
# 7: b 2  7 3 
+0

मैंने कभी भी 'data.table' के साथ काम नहीं किया है, केवल इसकी महिमा और महिमा के बारे में सुना है :)। –

+0

@PaulHiemstra लेकिन आपने इसके साथ काम किया है। क्या यह केवल एक बार था? http://www.r-statistics.com/2011/08/comparison-of-ave-ddply-and-data-table/ –

+0

यह एक छोटा परीक्षण था जिसे मैंने किसी और से कॉपी किया था, इसमें निर्दिष्ट एसओ पोस्ट देखें वह पोस्ट मैं डेटा.table सीखने का मतलब रहा हूं, लेकिन वास्तविक आवश्यकता को कभी महसूस नहीं किया है। शायद मेरा डेटा काफी बड़ा नहीं है :)। –

5

इस बीच, आप भी dplyr उपयोग कर सकते हैं:


यहाँ एक data.table तरीका है। अपने data.frame MyData

library(dplyr) 
mydata %>% group_by(CustomerID) %>% mutate(TripCounter = row_number()) 
0

कहा जाता है, तो यह सही जवाब नहीं है, लेकिन छोरों के लिए की तुलना में कुछ दिलचस्प बातें दिखा रहा है, vectorization तेजी से अनुक्रमिक अद्यतन करने के बारे में परवाह नहीं करता है। एक < -read.table (textConnection ( "CustomerID TripDate 1 1/3/2013 1 1/4/2013 1 1/9/2013 2 2/1/2013 2 2/4/2013 3 1/2/2013 "), हेडर = TRUE)

a <- a %>% 
group_by(CustomerID,TripDate) # must in order 

res <- rep(1, nrow(a)) #base @ 1 
res[2:6] <-sapply(2:6, function(i)if(a$CustomerID[i]== a$CustomerID[i - 1]) {res[i] = res[i-1]+1} else {res[i]= res[i]}) 
a$TripeCounter <- res 
संबंधित मुद्दे