সারি-সারি একটি আর ডাটাফ্রেম তৈরি করা


107

আমি আর-তে একটি ডাটাফ্রেম সারি-সারি সারি তৈরি করতে চাই some একটি একক-সারির ডেটাফ্রেম এবং তালিকা সূচকে একের সাথে এগিয়ে নিয়ে যান। অবশেষে, do.call(rbind,)তালিকায়।

এটি কাজ করার সময়, এটি খুব জটিল মনে হয়। একই লক্ষ্য অর্জনের জন্য কি সহজ উপায় নেই?

স্পষ্টতই আমি applyএমন কেসগুলিকে উল্লেখ করি যেখানে আমি কিছু ফাংশন ব্যবহার করতে পারি না এবং স্পষ্টতই সারিবদ্ধভাবে ডেটা ফ্রেম সারি তৈরি করা দরকার। কমপক্ষে, pushশেষের সূচকটি স্পষ্টভাবে ট্র্যাক করে রাখার পরিবর্তে কোনও তালিকার শেষে যাওয়ার কোনও উপায় আছে কি?


1
আপনি append()[যা সম্ভবত সন্নিবেশ হিসাবে নামকরণ করা উচিত] ব্যবহার করতে পারেন বা c()তালিকার শেষে আইটেমগুলি যুক্ত করতে, যদিও এখানে আপনাকে সহায়তা করবে না।
হ্যাটম্যাট্রিক্স

সেখানে আর অনেক ফাংশন যে ফিরতি তথ্য ফ্রেম যদি না আপনি তাদের ফিরে না হয় [সারি ভিত্তিক] থেকে lapply(), Map(), ইত্যাদি, কিন্তু আপনি কটাক্ষপাত করা করতে পারেন aggregate(), dapply() {heR.Misc}এবং cast() {reshape}দেখতে আপনার কর্ম এই দ্বারা পরিচালিত করা যাবে না যদি ফাংশন (এই সমস্ত রিটার্ন ডেটা ফ্রেম)।
হ্যাটম্যাট্রিক্স

উত্তর:


96

এগুলি সংযোজন বা ব্যবহার করে আপনি সারিবদ্ধভাবে তাদের বৃদ্ধি করতে পারেন rbind()

এর অর্থ এই নয় যে আপনার উচিত। ডায়ামোনিকલી ক্রমবর্ধমান কাঠামোগুলি আর-এ কোড দেওয়ার সবচেয়ে স্বল্পতম উপায় is

আপনি যদি পারেন তবে আপনার সম্পূর্ণ ডেটা বরাদ্দ করুন front ফ্রন্ট আপ ফ্রেম করুন:

N <- 1e4  # total number of rows to preallocate--possibly an overestimate

DF <- data.frame(num=rep(NA, N), txt=rep("", N),  # as many cols as you need
                 stringsAsFactors=FALSE)          # you don't know levels yet

এবং তারপরে আপনার ক্রিয়াকলাপগুলির সময় একবারে সারি প্রবেশ করান

DF[i, ] <- list(1.4, "foo")

এটি যথেচ্ছ ডেটা.ফ্রেমের জন্য কাজ করা উচিত এবং আরও বেশি দক্ষ হতে হবে। আপনি যদি ওভারশট করেন তবে আপনি সর্বদা শেষে খালি সারিগুলি সঙ্কুচিত করতে পারেন।


6
1.4-কে অক্ষর মোডে চাপিয়ে না দেওয়ার জন্য আপনি 10 এর পরিবর্তে এন এবং সি (1.4, "foo") এর পরিবর্তে (1.4, "foo") লিখতে চান না?
হ্যাটম্যাট্রিক্স

হ্যাঁ, আমি ডেটা.ফ্রেম তৈরিতে এন ব্যবহার করতে চাইছিলাম। এছাড়াও, খুব ভাল ক্যাচটি আড্ডায় জবরদস্তি করে - আমি এটি মিস করেছি।
ডার্ক এডেলবুয়েটেল

1
মন্তব্যে না রেখে উত্তরটি সম্পাদনা করা ভাল। আমি এই উত্তরটি ছাঁটাইতে চেষ্টা করে বিভ্রান্ত হয়ে পড়েছিলাম।
ব্যবহারকারী

4
data.tableডেটা.ফ্রেম ব্যবহার করে প্রাক-বরাদ্দের চেয়ে আরও দ্রুত বলে মনে হচ্ছে। এখানে পরীক্ষা করা হচ্ছে: stackoverflow.com/a/11486400/636656
আরি বি ফ্রেডম্যান

এটি কি আর 3.1-তে সত্য যেখানে এটি আরও দ্রুত হওয়া উচিত?
ব্যবহারকারী জেটি

49

যে কেউ এতে সারি যুক্ত করতে পারে NULL:

df<-NULL;
while(...){
  #Some code that generates new row
  rbind(df,row)->df
}

এই ক্ষেত্রে

df<-NULL
for(e in 1:10) rbind(df,data.frame(x=e,square=e^2,even=factor(e%%2==0)))->df
print(df)

3
এটি একটি ম্যাট্রিক্সকে আউটপুট দেয়, কোনও ডেটা ফ্রেম নয়
ওলগা

1
@ ওলগা কেবলমাত্র যদি আপনি সমান ধরণের উপাদানগুলির সারি বেঁধে রাখেন - বিটিডাব্লু সেই ক্ষেত্রে এটি sapply(বা ভেক্টরাইজ) করা এবং স্থানান্তর করা ভাল।
এমবিকিউ

1
@mbq ঠিক আমি কী করছি আমি এটিও দেখতে পেয়েছি যে আপনি যদি df <-data.frame () দিয়ে এটি আরম্ভ করেন তবে এটি একটি ডেটা ফ্রেমের আউটপুট দেয়।
ওলগা

9

এটি [যেটির সাথে সমান ] do.call(rbind,)এর আউটপুটটিতে কীভাবে ব্যবহার করা যায় তার একটি নিরীহ উদাহরণ Map()islapply()

> DF <- do.call(rbind,Map(function(x) data.frame(a=x,b=x+1),x=1:3))
> DF
  x y
1 1 2
2 2 3
3 3 4
> class(DF)
[1] "data.frame"

আমি এই প্রায়শই প্রায়শই ব্যবহার করি।


8

আমি আরসিপ্পিকে এত বেশি পছন্দ করার কারণটি হ'ল আমি সবসময় আর কোর কীভাবে চিন্তা করি তা পাই না এবং আরসিপ্পির সাথে প্রায়শই না হয়, আমার দরকার হয় না।

দার্শনিকভাবে বলতে গেলে, আপনি কার্যকরী দৃষ্টান্তের সাথে পাপ অবস্থায় রয়েছেন, যা প্রতিটি মান প্রতিটি অন্যান্য মানের থেকে পৃথকভাবে প্রদর্শিত হয় তা নিশ্চিত করার চেষ্টা করে; একটি মান পরিবর্তন করা কখনই অন্য মানতে দৃশ্যমান পরিবর্তনের কারণ হতে পারে না, সিটিতে পয়েন্টার ভাগ করে নেওয়ার মাধ্যমে আপনি যেভাবে পান get

সমস্যাগুলি দেখা দেয় যখন ফাংশনাল প্রোগ্রামিং ছোট কারুশিল্পটি পথ থেকে সরে যেতে সংকেত দেয় এবং ছোট কারুকাজটি "আমি বাতিঘর" বলে উত্তর দেয়। আপনি এর মধ্যে প্রক্রিয়া করতে চান এমন একটি বড় অবজেক্টে দীর্ঘ ধারাবাহিক পরিবর্তন করা আপনাকে বাতিঘর অঞ্চলগুলিতে বর্গক্ষেত্র দেয়।

সি ++ এসটিএলে, push_back()একটি জীবনযাপন। এটি কার্যকরী হওয়ার চেষ্টা করে না, তবে এটি সাধারণ প্রোগ্রামিং আইডিয়ামগুলিকে দক্ষতার সাথে সমন্বিত করার চেষ্টা করে

পর্দার পিছনে কিছু চতুরতার সাথে আপনি মাঝে মাঝে প্রতিটি বিশ্বে একটি পা রাখার ব্যবস্থা করতে পারেন। স্ন্যাপশট ভিত্তিক ফাইল সিস্টেমগুলি একটি ভাল উদাহরণ (যা ইউনিয়ন মাউন্টগুলির মত ধারণাগুলি থেকে উদ্ভূত হয়েছে, যা উভয় পক্ষকেও চালিত করে)।

আর কোর এটি করতে চাইলে অন্তর্নিহিত ভেক্টর স্টোরেজ ইউনিয়ন মাউন্টের মতো কাজ করতে পারে। ভেক্টর স্টোরেজ সম্পর্কিত 1:Nএকটি রেফারেন্স সাবস্ক্রিপ্টগুলির জন্য বৈধ হতে পারে , অন্য একই স্টোরেজের অন্য রেফারেন্স সাবস্ক্রিপ্টগুলির জন্য বৈধ 1:(N+1)। সেখানে সংরক্ষিত স্টোরেজ থাকতে পারে যা এখনও বৈধভাবে কোনও কিছু দ্বারা বৈধভাবে রেফারেন্স করা যায় না তবে দ্রুত করার জন্য সুবিধাজনক push_back()। বিদ্যমান বিদ্যমান রেফারেন্সটিকে বৈধ বলে মনে করে এমন সীমার বাইরে যুক্ত করার সময় আপনি কার্যকরী ধারণাটি লঙ্ঘন করবেন না।

অবশেষে সারিগুলি ক্রমবর্ধমানভাবে সংযোজন করার পরে, আপনি সংরক্ষিত স্টোরেজটি শেষ করেছেন। আপনার কিছু পরিমাণের নতুন কপি তৈরি করতে হবে, স্টোরেজটি কিছু বৃদ্ধি দিয়ে বৃদ্ধি করা উচিত। বরাদ্দ বাড়ানোর সময় আমি যে এসটিএল বাস্তবায়নগুলি ব্যবহার করেছি সেগুলি 2 দ্বারা স্টোরেজকে বহুগুণ করে। আমি ভেবেছিলাম আমি আর ইন্টারনালগুলিতে পড়েছি যে এখানে একটি মেমরি কাঠামো রয়েছে যেখানে স্টোরেজ 20% বৃদ্ধি পায়। যে কোনও উপায়ে, যুক্ত হওয়া সামগ্রীর সংখ্যার তুলনায় লোগারিথমিক ফ্রিকোয়েন্সি সহ গ্রোথ অপারেশন ঘটে। মোড়কযুক্ত ভিত্তিতে, এটি সাধারণত গ্রহণযোগ্য।

পর্দার আড়ালে কৌশলগুলি খারাপ হতে দেখেছি, আরও খারাপ। আপনি যখনই push_back()ডেটাফ্রেমে একটি নতুন সারিতে প্রতিবার নেবেন তখন একটি শীর্ষ স্তরের সূচি কাঠামো অনুলিপি করা দরকার। নতুন সারিটি কোনও পুরানো কার্যকরী মানগুলিকে প্রভাবিত না করে ভাগ করে নেওয়া উপস্থাপনায় যুক্ত হতে পারে। এমনকি এগুলি আবর্জনা সংগ্রহকারীকে আরও জটিল করে তুলবে বলে আমি মনে করি না; যেহেতু আমি push_front()সমস্ত রেফারেন্স প্রস্তাব করছি না বরাদ্দ করা ভেক্টর স্টোরেজের সামনের অংশের উপসর্গ রেফারেন্স।


2

ডার্ক এডেলবুয়েটেলের উত্তর সবচেয়ে ভাল; এখানে আমি কেবল নোট করেছি যে আপনি ডেটা ফ্রেমের মাত্রা বা ডেটা ধরণের প্রাক-নির্দিষ্টকরণ না করে পালিয়ে যেতে পারেন, যা আপনার কাছে একাধিক ডেটা প্রকার এবং প্রচুর কলাম থাকলে কখনও কখনও কার্যকর হয়:

row1<-list("a",1,FALSE) #use 'list', not 'c' or 'cbind'!
row2<-list("b",2,TRUE)  

df<-data.frame(row1,stringsAsFactors = F) #first row
df<-rbind(df,row2) #now this works as you'd expect.

মানে df<-rbind(df, row2)?
টিমোথি সি কুইন

1

আমি ম্যাট্রিক্স ছাড়াই কাঁচা করে ডেটাফ্রেম তৈরি করার উপায় খুঁজে পেয়েছি।

স্বয়ংক্রিয় কলামের নাম সহ

df<-data.frame(
        t(data.frame(c(1,"a",100),c(2,"b",200),c(3,"c",300)))
        ,row.names = NULL,stringsAsFactors = FALSE
    )

কলামের নাম সহ

df<-setNames(
        data.frame(
            t(data.frame(c(1,"a",100),c(2,"b",200),c(3,"c",300)))
            ,row.names = NULL,stringsAsFactors = FALSE
        ), 
        c("col1","col2","col3")
    )

0

আপনার যদি ভেক্টরগুলি সারি হয়ে c()যাওয়ার নিয়ত করে থাকে তবে তাদের ব্যবহার করে সম্মতি দিন, ম্যাট্রিক্সকে সারি-সারি সারি করে দিন এবং সেই ম্যাট্রিক্সকে ডেটা ফ্রেমে রূপান্তর করুন।

উদাহরণস্বরূপ, সারিগুলি

dummydata1=c(2002,10,1,12.00,101,426340.0,4411238.0,3598.0,0.92,57.77,4.80,238.29,-9.9)
dummydata2=c(2002,10,2,12.00,101,426340.0,4411238.0,3598.0,-3.02,78.77,-9999.00,-99.0,-9.9)
dummydata3=c(2002,10,8,12.00,101,426340.0,4411238.0,3598.0,-5.02,88.77,-9999.00,-99.0,-9.9)

এভাবে একটি ডেটা ফ্রেমে রূপান্তর করা যায়:

dummyset=c(dummydata1,dummydata2,dummydata3)
col.len=length(dummydata1)
dummytable=data.frame(matrix(data=dummyset,ncol=col.len,byrow=TRUE))

স্বীকারোক্তি সহ, আমি 2 টি বড় সীমাবদ্ধতাগুলি দেখতে পাচ্ছি: (1) এটি কেবলমাত্র একক-মোড ডেটার সাথে কাজ করে এবং (2) এটি কাজ করার জন্য আপনাকে অবশ্যই আপনার চূড়ান্ত # কলামগুলি জানতে হবে (যেমন, আমি ধরে নিচ্ছি যে আপনি কোনও সাথে কাজ করছেন না জীর্ণ অ্যারে যার সর্বাধিক সারি দৈর্ঘ্য অজানা অবরোহমার্গী )।

এই সমাধানটি সহজ বলে মনে হচ্ছে, তবে আর-তে টাইপ রূপান্তর সম্পর্কে আমার অভিজ্ঞতা থেকে, আমি নিশ্চিত যে এটি নতুন প্রতিদ্বন্দ্বীতা তৈরি করে। কেউ কি এটার উপর মন্তব্য করতে পার?


0

আপনার নতুন সারিটির ফর্ম্যাটের উপর নির্ভর করে আপনি tibble::add_rowযদি নতুন সারিটি সহজ হয় এবং "মান-জোড়া" এ নির্দিষ্ট করতে পারেন তবে আপনি ব্যবহার করতে পারেন। অথবা আপনি ব্যবহার করতে পারেন dplyr::bind_rows, "do.call (rbind, dfs) ​​এর সাধারণ প্যাটার্নের একটি কার্যকর প্রয়োগ"।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.