2011-12-25 13 views
7

में डेटा फ्रेम का निर्माण करना मैं Rcpp फ़ंक्शन में डेटा फ्रेम बनाना चाहता हूं, लेकिन जब मुझे यह मिलता है, तो यह वास्तव में डेटा फ्रेम की तरह नहीं दिखता है। मैंने वैक्टर आदि को धक्का देने की कोशिश की है, लेकिन यह एक ही चीज की ओर जाता है। पर विचार करें:आरसीपीपी

RcppExport SEXP makeDataFrame(SEXP in) { 
    Rcpp::DataFrame dfin(in); 
    Rcpp::DataFrame dfout; 
    for (int i=0;i<dfin.length();i++) { 
     dfout.push_back(dfin(i)); 
    } 

    return dfout; 
} 
आर में

:

> .Call("makeDataFrame",mtcars,"myPkg") 
[[1]] 
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4 
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7 
[31] 15.0 21.4 

[[2]] 
[1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4 

[[3]] 
[1] 160.0 160.0 108.0 258.0 360.0 225.0 360.0 146.7 140.8 167.6 167.6 275.8 
[13] 275.8 275.8 472.0 460.0 440.0 78.7 75.7 71.1 120.1 318.0 304.0 350.0 
[25] 400.0 79.0 120.3 95.1 351.0 145.0 301.0 121.0 

[[4]] 
[1] 110 110 93 110 175 105 245 62 95 123 123 180 180 180 205 215 230 66 52 
[20] 65 97 150 150 245 175 66 91 113 264 175 335 109 

[[5]] 
[1] 3.90 3.90 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 3.92 3.07 3.07 3.07 2.93 
[16] 3.00 3.23 4.08 4.93 4.22 3.70 2.76 3.15 3.73 3.08 4.08 4.43 3.77 4.22 3.62 
[31] 3.54 4.11 

[[6]] 
[1] 2.620 2.875 2.320 3.215 3.440 3.460 3.570 3.190 3.150 3.440 3.440 4.070 
[13] 3.730 3.780 5.250 5.424 5.345 2.200 1.615 1.835 2.465 3.520 3.435 3.840 
[25] 3.845 1.935 2.140 1.513 3.170 2.770 3.570 2.780 

[[7]] 
[1] 16.46 17.02 18.61 19.44 17.02 20.22 15.84 20.00 22.90 18.30 18.90 17.40 
[13] 17.60 18.00 17.98 17.82 17.42 19.47 18.52 19.90 20.01 16.87 17.30 15.41 
[25] 17.05 18.90 16.70 16.90 14.50 15.50 14.60 18.60 

[[8]] 
[1] 0 0 1 1 0 1 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 1 0 1 0 0 0 1 

[[9]] 
[1] 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 

[[10]] 
[1] 4 4 4 3 3 3 3 4 4 4 4 3 3 3 3 3 3 4 4 4 3 3 3 3 3 4 5 5 5 5 5 4 

[[11]] 
[1] 4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2 
+4

मैं Rcpp बारे में कुछ पता नहीं है, लेकिन होगा यह आपको यह जानने में मदद करता है कि आर में ही, सभी डेटा फ्रेम वास्तव में सूचियां हैं? – joran

उत्तर

6

ऐसा लगता है कि आरसीपीपी उचित डेटा लौटा सकता है, अगर आप स्पष्ट रूप से नामों की आपूर्ति करते हैं। मुझे यकीन है कि कैसे मनमाने ढंग से नाम

mkdf <- ' 
    Rcpp::DataFrame dfin(input); 
    Rcpp::DataFrame dfout; 
    for (int i=0;i<dfin.length();i++) { 
     dfout.push_back(dfin(i)); 
    } 

    return Rcpp::DataFrame::create(Named("x")= dfout(1), Named("y") = dfout(2)); 
' 
library(inline) 
test <- cxxfunction(signature(input="data.frame"), 
           mkdf, plugin="Rcpp") 

test(input=head(iris)) 
+0

तो जाहिर है, हम डेटाफ्रेम नहीं बना सकते हैं जहां रन टाइम पर कॉलम की संख्या तय की जाती है? – highBandWidth

+6

यदि 'हम' से आपका मतलब है आप और मैं, तो यह संभवतः सही है;) – baptiste

+0

मुझे याद है कि आप रन-टाइम पर कॉलम की संख्या निर्धारित कर सकते हैं और एक संबंधित डेटाफ्रेम बना सकते हैं, क्योंकि मुझे एक बार भी आवश्यकता थी। हालांकि आप उस स्थिति में स्थैतिक निर्माण का उपयोग नहीं कर सकते हैं। –

0

मैं Joran से सहमत हुई। आर के भीतर से बुलाए गए एक सी फ़ंक्शन का आउटपुट "इन" और "आउट" दोनों के सभी तर्कों की एक सूची है, इसलिए डेटा फ़्रेम के प्रत्येक "कॉलम" को सी फ़ंक्शन कॉल में तर्क के रूप में दर्शाया जा सकता है। एक बार सी फंक्शन कॉल का नतीजा आर में होता है, जो कुछ भी किया जाना बाकी है, सूची सूची का उपयोग करके उन सूची तत्वों को निकालना और उन्हें उचित नाम देना है।

+0

हू? हम यहां सी ++ और आरसीपीपी के बारे में बात कर रहे हैं, सादे सी –

12

संक्षेप में:

  • DataFrames वास्तव में सिर्फ एक आम लंबाई के लिए होने का जोड़ा प्रतिबंध के साथ सूचियों की तरह हैं, इसलिए वे सबसे अच्छा स्तंभ द्वारा स्तंभ निर्माण कर रहे हैं।

  • हमारे यूनिट परीक्षणों को देखने के लिए सबसे अच्छा तरीका अक्सर होता है। उसका inst/unitTests/runit.DataFrame.R DataFrame कक्षा के लिए परीक्षणों का पुनर्गठन करता है।

  • आपको सदस्य फ़ंक्शन Rcpp में भी मिला है जिसे हमने एसटीएल के साथ सुविधा और समानता के लिए जोड़ा है। हम चेतावनी देते हैं कि इसकी अनुशंसा नहीं की जाती है: आर ऑब्जेक्ट्स के तरीके के साथ मतभेदों के कारण, हमें अनिवार्य रूप से हमेशा पूर्ण प्रतियां करने की आवश्यकता होती है .push_backबहुत कुशल नहीं है

  • मुझे अक्सर यहां जवाब देने के बावजूद, rcpp-devel आरसीपीपी प्रश्नों के लिए एक बेहतर जगह सूचीबद्ध करता है।

+1

नहीं, मेरे पास push_back की तुलना में डेटा फ्रेम में कुछ जोड़ने का बेहतर तरीका नहीं है। मैं उस समाधान में डालता हूं जिसके साथ मैं आ सकता हूं।एक आंतरिक कार्य 'बढ़ो' है। हालांकि इसे इंगित करने के लिए +1। – highBandWidth

+0

मैं कॉलम पहले (पॉजिस्बली प्री-आवंटन) बढ़ा दूंगा और फिर उन्हें डेटा.फ्रेम में इकट्ठा करूंगा। –

+0

क्या स्थिर 'निर्माण' के अलावा डेटा फ्रेम में स्तंभों को इकट्ठा करने का कोई तरीका है? मुझे कुछ भी नहीं मिला जो यूनिट परीक्षणों में करता है। – highBandWidth

6

से जानकारी का उपयोग कर के साथ अपने उदाहरण को यह अनुकूल करने के लिए नहीं कर रहा हूँ @ बैप्टिस्ट के answer, यह क्या अंत में एक अच्छी तरह से गठन डेटा फ्रेम दे रहा है:

RcppExport SEXP makeDataFrame(SEXP in) { 
    Rcpp::DataFrame dfin(in); 
    Rcpp::DataFrame dfout; 
    Rcpp::CharacterVector namevec; 
    std::string namestem = "Column Heading "; 
    for (int i=0;i<2;i++) { 
     dfout.push_back(dfin(i)); 
     namevec.push_back(namestem+std::string(1,(char)(((int)'a') + i))); 
    } 
    dfout.attr("names") = namevec; 
    Rcpp::DataFrame x; 
    Rcpp::Language call("as.data.frame",dfout); 
    x = call.eval(); 
    return x; 
} 

मैं लगता है कि बिंदु बनी हुई है कि यह push_back के कारण अक्षम हो सकता है (suggested @Dirk द्वारा) और दूसरा भाषा कॉल मूल्यांकन। मैंने आरसीपीपी यूनिट टेस्ट देखा, और अभी तक कुछ बेहतर के साथ आने में सक्षम नहीं है। किसी के पास कोई विचार है?

अपडेट: (! धन्यवाद)

@ डिर्क के सुझावों का उपयोग करना, यह एक सरल, कुशल समाधान लगता है: वास्तव में,

RcppExport SEXP makeDataFrame(SEXP in) { 
    Rcpp::DataFrame dfin(in); 
    Rcpp::List myList(dfin.length()); 
    Rcpp::CharacterVector namevec; 
    std::string namestem = "Column Heading "; 
    for (int i=0;i<dfin.length();i++) { 
     myList[i] = dfin(i); // adding vectors 
     namevec.push_back(namestem+std::string(1,(char)(((int)'a') + i))); // making up column names 
    } 
    myList.attr("names") = namevec; 
    Rcpp::DataFrame dfout(myList); 
    return dfout; 
} 
+0

मैं आर स्तर पर 'as.data.frame' करना चाहता हूं। –

+0

मुझे अभी भी समझ में नहीं आता कि आपका कार्य क्या करना है। इनपुट पर डेटा.फ्रेम क्यों है? आपकी स्ट्रिंग हैंडलिंग * रास्ता * बहुत जटिल है (फिर से, इकाई परीक्षणों या आरसीपीपी में स्ट्रिंग वैक्टर के लिए दस्तावेज़) देखें। –

+0

फ़ंक्शन कुछ भी उपयोगी नहीं करता है। मैं सिर्फ डेटा फ्रेम बनाने में सक्षम होना चाहता हूं। मैं वास्तव में अपने स्वयं के कम्प्यूटेशंस/डेटा से फ्रेम बना रहा हूं, लेकिन मुझे डेटा फ्रेम में कॉलम वैक्टर और नामों को एक साथ रखने के लिए एक टेम्पलेट की आवश्यकता है, जहां कॉलम वैक्टर आदि बनाना सी ++ में किया जाता है क्योंकि उन गणनाओं में महंगे हैं मेरा कार्यक्रम कॉलम हेडिंग/स्ट्रिंग हैंडलिंग अनिवार्य रूप से कचरा है जिसे मुझे परवाह नहीं है। – highBandWidth

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