2010-04-01 7 views
15

मैं आर में डेटा फ्रेम में लूप से लिखने की कोशिश कर रहा हूं, उदाहरण के लिए इस तरह एक लूप>आर में एक लूप से डेटाफ्रेम को लिखना

for (i in 1:20) { 
print(c(i+i,i*i,i/1))} 

और 3 कॉलों की प्रत्येक पंक्ति को तीन कॉलम के साथ डेटा फ्रेम में लिखने के लिए, ताकि प्रत्येक पुनरावृत्ति एक नई पंक्ति पर लेता है। मैंने मैट्रिक्स का उपयोग करने की कोशिश की है, ncol = 3 के साथ और पंक्तियों से भरा है, लेकिन केवल लूप से अंतिम आइटम प्राप्त करें।

धन्यवाद।

उत्तर

22

आप rbind इस्तेमाल कर सकते हैं:

d <- data.frame() 
for (i in 1:20) {d <- rbind(d,c(i+i, i*i, i/1))} 
+2

ध्यान दें कि यह शायद कम से कम कुशल समाधान प्रस्तावित है। बहुत छोटे डेटा सेट के लिए इससे कोई फर्क नहीं पड़ता है, लेकिन यदि आप कुशल होना चाहते हैं तो आपको वास्तव में लूप के अंदर आरबीआईंड या सीबिंड का उपयोग नहीं करना चाहिए। – Dason

4

पाश के लिए साइड इफेक्ट है, तो ऐसा करने का हमेशा की तरह पाश से पहले एक खाली dataframe बनाने के लिए और उसके बाद प्रत्येक यात्रा पर यह करने के लिए जोड़ है। आप इसे सही आकार में तुरंत चालू कर सकते हैं और फिर अपने मानों को प्रत्येक पुनरावृत्ति पर पंक्ति में निर्दिष्ट कर सकते हैं, या फिर इसमें जोड़ सकते हैं और rbind() का उपयोग करके पूरी चीज़ को फिर से सौंप सकते हैं।

पूर्व दृष्टिकोण के बड़े डेटासेट के लिए बेहतर प्रदर्शन होगा।

+0

इन दोनों उत्तरों के लिए धन्यवाद, ith पंक्ति को मान असाइन करने के लिए आपका मतलब कुछ ऐसा है, (यह वास्तव में काम नहीं करता है)। साथ ही, क्या इस तरह अज्ञात संख्याओं के साथ डेटाफ्रेम के साथ काम करेगा? rm (घ) घ <- data.frame (Nrow = 20, ncol = 3) (1:20 में i) {के लिए डी [मैं,] <- सी (मैं मैं +, मैं मैं *, i/1)} – CCID

+0

आपने "अज्ञात पंक्तियों" क्यों नहीं कहा जब आपके उदाहरण में 1:20 में है? यदि पंक्तियों की अज्ञात संख्या है, तो आपको किसी अन्य उत्तर के सुझाव के रूप में rbind जैसे कुछ उपयोग करने की आवश्यकता होगी। प्रतीत होता है कि –

6

यदि आपके सभी मान एक ही प्रकार है और आप पंक्तियों की संख्या पता है, तुम निम्नलिखित रास्ते में एक मैट्रिक्स (यह बहुत तेजी से हो जाएगा) का उपयोग कर सकते हैं:

d <- matrix(nrow=20, ncol=3) 
for (i in 1:20) { d[i,] <- c(i+i, i*i, i/1)} 

आप एक डेटा फ्रेम की जरूरत है , आप rbind (के रूप में एक और उत्तर पता चलता है) या कार्यों पैकेज plyr से इस तरह उपयोग कर सकते हैं,:

library(plyr) 
ldply(1:20, function(i)c(i+i, i*i, i/1)) 
10

एक और तरीका होगा

do.call("rbind", sapply(1:20, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE)) 


    [,1] [,2] [,3] 
[1,] 2 1 1 
[2,] 4 4 2 
[3,] 6 9 3 
[4,] 8 16 4 
[5,] 10 25 5 
[6,] 12 36 6 

यदि आप simplify = FALSE निर्दिष्ट नहीं करते हैं, तो आपको t का उपयोग करके परिणाम स्थानांतरित करना होगा। यह बड़ी संरचनाओं के लिए थकाऊ हो सकता है।

यह समाधान विशेष रूप से आसान है यदि आपके पास बड़ी तरफ डेटा सेट है और/या आपको इसे कई बार दोहराने की आवश्यकता है।

मैं इस "धागे" में समाधान के कुछ समय प्रदान करता हूं।

> system.time(do.call("rbind", sapply(1:20000, FUN = function(i) c(i+i,i*i,i/1), simplify = FALSE))) 
    user system elapsed 
    0.05 0.00 0.05 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1))) 
    user system elapsed 
    0.14 0.00 0.14 

> system.time({d <- matrix(nrow=20000, ncol=3) 
+ for (i in 1:20000) { d[i,] <- c(i+i, i*i, i/1)}}) 
    user system elapsed 
    0.10 0.00 0.09 

> system.time(ldply(1:20000, function(i)c(i+i, i*i, i/1))) 
    user system elapsed 
    62.88 0.00 62.99 
+0

'sapply' तेजी से प्राप्त हुआ है (कम से कम मेरी मशीन पर) इसे लिखते समय (** 1: 2e4 **, FUN = function (i) ** c (2 * i, i^2, i/1) **, सरलीकृत = गलत) –

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