आर

2015-03-10 3 views
7

में शर्तों के आधार पर मैं एक data.table कि इसआर

dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,200,300,400), 
       Amount2=c(1500,1500,2400,2400),Dupl=c(1,0,1,0)) 

    ID Amount1 Amount2 Dupl 
1: A  100 1500 1 
2: A  200 1500 0 
3: B  300 2400 1 
4: B  400 2400 0 

मैं प्रत्येक पंक्ति dupl कॉलम में एक 1 है कि नकल और AMOUNT2 साथ Amount1 मूल्य प्रतिस्थापित करने की आवश्यकता की तरह लग रहा है डुप्लीकेट पंक्तियों बनाएं उस डुप्लिकेट पंक्ति में मूल्य। इसके अलावा मुझे डुप्लिकेट पंक्ति को डुप्ल में मान 2 देने की आवश्यकता है। इसका मतलब है कि इसे इस तरह दिखना चाहिए:

ID Amount1 Amount2 Dupl 
1: A  100 1500 1 
2: A 1500 1500 2 
3: A  200 1500 0 
4: B  300 2400 1 
5: B 2400 2400 2 
6: B  400 2400 0 

किसी भी मदद की बहुत सराहना की जाती है! सधन्यवाद,

टिम

+3

क्या कोई अन्य नियम हैं जिन्हें हमें जानने की आवश्यकता है? किसी दिए गए आईडी के लिए चार पंक्तियां हो सकती हैं? क्या "डुप्ल" कॉलम में "1" और "2" के अलावा अन्य मान हैं? – A5C1D2H2I1M1N2O1R2T1

उत्तर

9

का उपयोग करते हुए आप

rbind(dt,dt[Dupl==1][,c('Amount1', 'Dupl') := list(Amount2, 2)]) 
+0

@ डेविड एडनबर्ग धन्यवाद, मैं आपके टेम्पलेट कोड का उपयोग करके 'rleid' के संदर्भ में भी सोच रहा था, लेकिन थोड़ा मुश्किल पाया गया। – akrun

3

यह आप के लिए क्या पूछ रहे हैं क्या करने के लिए लगता है। शायद थोड़ा परिष्कृत किया जा सकता ...

library(splitstackshape) 
expandRows(dt, dt$Dupl+1, count.is.col = FALSE)[ 
    Dupl != 0, Dupl := cumsum(Dupl), by = ID][ 
    , Amount1 := ifelse(Dupl > 1, Amount2[-1], Amount1)][] 
# ID Amount1 Amount2 Dupl 
# 1: A  100 1500 1 
# 2: A 1500 1500 2 
# 3: A  200 1500 0 
# 4: B  300 2400 1 
# 5: B 2400 2400 2 
# 6: B  400 2400 0 
6

dplyr

require("data.table") 
require("dplyr") 

#data 
dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,200,300,400), 
       Amount2=c(1500,1500,2400,2400),Dupl=c(1,0,1,0)) 
#result 
rbind(dt, 
     dt %>% 
     filter(Dupl==1) %>% 
     mutate(Dupl=2, 
       Amount1=Amount2)) 

# ID Amount1 Amount2 Dupl 
# 1: A  100 1500 1 
# 2: A  200 1500 0 
# 3: B  300 2400 1 
# 4: B  400 2400 0 
# 5: A 1500 1500 2 
# 6: B 2400 2400 2 
+0

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

4

की कोशिश कर सकते आप कर सकते हैं rbind सही परिवर्तनों के साथ उप setted डेटा की एक प्रतिलिपि किया गया:

rbind(dt,copy(dt[Dupl==1])[,Amount1:=Amount2][,Dupl:=Dupl+1]) 
    ID Amount1 Amount2 Dupl 
1: A  100 1500 1 
2: A  200 1500 0 
3: B  300 2400 1 
4: B  400 2400 0 
5: A 1500 1500 2 
6: B 2400 2400 2 

वैकल्पिक रूप से, आप उप-सेटिंग द्वारा डुप्लिकेट प्राप्त कर सकते हैं, और फिर मध्यवर्ती चरण का उपयोग करके डुप्लिकेट पंक्तियों को बदल सकते हैं। यह प्रश्न के उदाहरण के रूप में मूल के बगल में डुप्लिकेट पंक्ति रखता है:

x <- dt[rep(seq(dt[,Dupl]),times=dt[,Dupl==1]+1)] 
x[duplicated(x),c("Amount1","Dupl"):=list(Amount2,Dupl+1)] 
x 
    ID Amount1 Amount2 Dupl 
1: A  100 1500 1 
2: A 1500 1500 2 
3: A  200 1500 0 
4: B  300 2400 1 
5: B 2400 2400 2 
6: B  400 2400 0 
+1

आप दूसरे समाधान में पहले चरण में 'x <- dt [rep (seq_len (.N), डुप्ल + 1 एल)] '' कर सकते हैं। ऐसा लगता है कि इस एकल चरण में 'डीटी' 3 बार कॉल करना एक बड़ा ओवरहेड है यदि 'dt' बड़ा है। –