2012-10-23 39 views
5

के साथ डेटा फ्रेम को कुशलता से बदलना मैं एक ऐसा प्रोग्राम लिखने की कोशिश कर रहा हूं जो एक बड़ा डेटा फ्रेम लेता है और उन मानों की संचयी आवृत्ति (आरोही क्रमबद्ध) द्वारा मूल्यों के प्रत्येक कॉलम को प्रतिस्थापित करता है। उदाहरण के लिए, यदि मूल्यों के स्तंभ हैं: 5, 8, 3, 5, 4, 3, 8, 5, 5, 1. फिर रिश्तेदार और संचयी आवृत्तियों हैं:संचयी आवृत्ति

  • 1: rel_freq = 0.1, cum_freq = 0,1
  • 3: rel_freq = 0.2, cum_freq = 0,3
  • 4: rel_freq = 0.1, cum_freq = 0,4
  • 5: rel_freq = 0.4, cum_freq = 0,8
  • 8: rel_freq = 0.2, cum_freq = 1.0

फिर मूल सह लम्बर बन जाता है: 0.8, 1.0, 0.3, 0.8, 0.4, 0.3, 1.0, 0.8, 0.8, 0.1

निम्नलिखित कोड इस ऑपरेशन को सही तरीके से करता है, लेकिन यह शायद नेस्टेड लूप के कारण खराब तरीके से स्केल करता है। कोई विचार यह कार्य अधिक कुशलतापूर्वक कैसे करें?

mydata = read.table(.....) 

totalcols = ncol(mydata) 
totalrows = nrow(mydata) 

for (i in 1:totalcols) { 
    freqtable = data.frame(table(mydata[,i])/totalrows) # create freq table 
    freqtable$CumSum = cumsum(freqtable$Freq) # calc cumulative freq 

    hashtable = new.env(hash=TRUE) 
    nrows = nrow(freqtable) 

    # store cum freq in hash 
    for (x in 1:nrows) { 
     dummy = toString(freqtable$Var1[x]) 
     hashtable[[dummy]] = freqtable$CumSum[x] 
    } 

    # replace original data with cum freq 
    for (j in 1:totalrows) { 
     dummy = toString(mydata[j,i]) 
     mydata[j,i] = hashtable[[dummy]] 
    } 
} 
+0

आप हमें एक दे सकते हैं [पुनरुत्पादित उदाहरण] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-exa mple)? –

उत्तर

2

यह for -loop बिना किसी एकल स्तंभ संभालता है:

R> x <- c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1) 
R> y <- cumsum(table(x)/length(x)) 
R> y[as.character(x)] 
    5 8 3 5 4 3 8 5 5 1 
0.8 1.0 0.3 0.8 0.4 0.3 1.0 0.8 0.8 0.1 
+0

उत्कृष्ट जवाब! मेरा प्रोग्राम इस कोड का उपयोग करके बहुत बेहतर है। धन्यवाद! – user1769120

1

यहाँ एक तरीका है।

  • match() एक में टिप्पणियों दो चर के साथ एक डेटा फ्रेम का उपयोग करते हुए प्रत्येक अपने उदाहरण डेटा

    d <- data.frame(var1 = c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1), 
           var2 = c(5, 8, 3, 5, 4, 3, 8, 5, 5, 1)) 
    

    उपयोग युक्त

    1. के लिए एक सरल समारोह table(x)/length(x) द्वारा दिए गए रिश्तेदार अनुपात के cumsum() उत्पन्न करते हैं, तो संचयी रकम की तालिका के नाम के साथ परिवर्तनीय, फिर
    2. संचयी रकम (और इसे नाम न दें) की तालिका से चयन करने के लिए आईडी मैचों का उपयोग करें

    इस तरह के एक कार्य है:

    f <- function(x) { 
        tab <- cumsum(table(x)/length(x)) 
        ind <- match(x, as.numeric(names(tab))) 
        unname(tab[ind]) 
    } 
    

    अभ्यास हम lapply() का उपयोग करें और एक डेटा फ्रेम करने के लिए मजबूर में:

    out <- data.frame(lapply(d, f)) 
    out 
    

    जो देता है:

    R> out 
        var1 var2 
    1 0.8 0.8 
    2 1.0 1.0 
    3 0.3 0.3 
    4 0.8 0.8 
    5 0.4 0.4 
    6 0.3 0.3 
    7 1.0 1.0 
    8 0.8 0.8 
    9 0.8 0.8 
    10 0.1 0.1 
    
  • +0

    धन्यवाद, मैं इसे आज़मा दूंगा। – user1769120

    संबंधित मुद्दे