ডেটা ফ্রেমের একটি তালিকা একটি ডেটা ফ্রেমে রূপান্তর করুন


336

আমার কোড রয়েছে যা এক জায়গায় ডেটা ফ্রেমের একটি তালিকা দিয়ে শেষ হয় যা আমি সত্যই একটি একক বড় ডেটা ফ্রেমে রূপান্তর করতে চাই।

আমি আগের প্রশ্ন থেকে কিছু পয়েন্টার পেয়েছি যা অনুরূপ কিছু হলেও জটিল করার চেষ্টা করছিল।

এখানে আমি যেটি দিয়ে শুরু করছি তার একটি উদাহরণ এখানে দেওয়া হয়েছে (উদাহরণের জন্য এটি চূড়ান্তভাবে সরলীকৃত):

listOfDataFrames <- vector(mode = "list", length = 100)

for (i in 1:100) {
    listOfDataFrames[[i]] <- data.frame(a=sample(letters, 500, rep=T),
                             b=rnorm(500), c=rnorm(500))
}

আমি বর্তমানে এটি ব্যবহার করছি:

  df <- do.call("rbind", listOfDataFrames)

এই প্রশ্নটিও দেখুন: স্ট্যাকওভারফ্লো
শেন

27
do.call("rbind", list)বাগ্ধারা কি আমি আগে হিসাবে ভাল ব্যবহার করা হয়েছে। আপনার প্রাথমিক প্রয়োজন কেন unlist?
ডার্ক এডেলবুয়েটেল

5
কেউ আমাকে do.call ("rbind", list) এবং rbind (list) এর মধ্যে পার্থক্য ব্যাখ্যা করতে পারে - আউটপুটগুলি কেন একই রকম নয়?
ব্যবহারকারী 6571411

1
@ user6571411 কারণ do.call () একের পর এক আর্গুমেন্ট ফেরত দেয় না তবে ফাংশনের আর্গুমেন্ট ধরে রাখতে একটি তালিকা ব্যবহার করে। Https://www.stat.berkeley.edu/~s133/Docall.html
মার্জোলিন ফোককেমা

উত্তর:


130

Dplyr প্যাকেজ থেকে বাইন্ড_স () ব্যবহার করুন:

bind_rows(list_of_dataframes, .id = "column_label")

5
সুন্দর সমাধান। .id = "column_label"তালিকার উপাদানগুলির নামের উপর ভিত্তি করে স্বতন্ত্র সারির নাম যুক্ত করে।
সিবো জিয়াং

10
যেহেতু এটি 2018 এবং dplyrএটি উভয়ই দ্রুত এবং ব্যবহারের জন্য একটি শক্ত সরঞ্জাম, তাই আমি এটি গ্রহণযোগ্য উত্তরে পরিবর্তন করেছি। বছর, তারা উড়ে!
জেডি লং

186

আরেকটি বিকল্প হ'ল প্লাইয়ার ফাংশনটি ব্যবহার করা:

df <- ldply(listOfDataFrames, data.frame)

এটি আসলটির চেয়ে সামান্য ধীর:

> system.time({ df <- do.call("rbind", listOfDataFrames) })
   user  system elapsed 
   0.25    0.00    0.25 
> system.time({ df2 <- ldply(listOfDataFrames, data.frame) })
   user  system elapsed 
   0.30    0.00    0.29
> identical(df, df2)
[1] TRUE

আমার ধারণা হ'ল do.call("rbind", ...)ব্যবহারটি সবচেয়ে দ্রুত পদ্ধতির হতে চলেছে যা আপনি পাবেন না যদি না আপনি (ক) ডেটা.ফ্রেমগুলির পরিবর্তে ম্যাট্রিক ব্যবহার করতে পারেন এবং (খ) ফাইনাল ম্যাট্রিক্স প্রিলোকল্ট করুন এবং এটি বাড়ানোর চেয়ে তাকে বরাদ্দ করুন unless ।

সম্পাদনা 1 :

হ্যাডলির মন্তব্যের ভিত্তিতে rbind.fillসিআরএএন- র সর্বশেষ সংস্করণটি এখানে :

> system.time({ df3 <- rbind.fill(listOfDataFrames) })
   user  system elapsed 
   0.24    0.00    0.23 
> identical(df, df3)
[1] TRUE

এটি আরবাইন্ডের চেয়ে সহজ এবং সামান্যতম দ্রুত (এই সময়গুলি একাধিক রান ধরে রাখে)। এবং যতদূর আমি এটি বুঝতে পারি, গিথুব- এ সংস্করণ এরplyr চেয়ে আরও দ্রুত।


28
plyr এর সাম্প্রতিক সংস্করণে rbind.fill যথেষ্ট দ্রুত do.call এবং rbind চেয়ে
হ্যাডলি

1
মজাদার. আমার জন্য rbind.fill ছিল দ্রুততম। যথেষ্ট অদ্ভুত, do.call / rbind অভিন্ন সত্যটি ফিরে আসেনি, এমনকি যদি আমি কোনও পার্থক্য খুঁজে নাও পাই। অন্য দুটি সমান ছিল তবে প্লাইয়ারটি ধীর ছিল।
ম্যাট ব্যানার

I()প্রতিস্থাপন করতে পারে data.frameআপনার ldplyকল
baptiste

4
এছাড়াও আছে melt.listপুনর্নির্মাণ মধ্যে (2)
Baptiste

do.call(function(...) rbind(..., make.row.names=F), df)আপনি যদি স্বয়ংক্রিয়ভাবে উত্পাদিত অনন্য রবনেমগুলি না চান তবে দরকারী।
smci

111

সম্পূর্ণতার উদ্দেশ্যে, আমি ভেবেছিলাম যে এই প্রশ্নের উত্তরগুলির জন্য একটি আপডেট দরকার। "আমার ধারণাটি হ'ল ব্যবহার do.call("rbind", ...)করা আপনার পক্ষে দ্রুততম পদ্ধতির হতে চলেছে ..." এটি সম্ভবত ২০১০ সালের মে এবং এর কিছুটা সময় পরে সত্য হয়েছিল, তবে প্রায় ২০১১ সালের সেপ্টেম্বরে প্যাকেজ সংস্করণ ১.৮.২ এ একটি নতুন ফাংশন rbindlistচালু হয়েছিল data.table, "এই যেমনটি করে do.call("rbind",l)তবে অনেক দ্রুত" এই মন্তব্য সহ । কত দ্রুত?

library(rbenchmark)
benchmark(
  do.call = do.call("rbind", listOfDataFrames),
  plyr_rbind.fill = plyr::rbind.fill(listOfDataFrames), 
  plyr_ldply = plyr::ldply(listOfDataFrames, data.frame),
  data.table_rbindlist = as.data.frame(data.table::rbindlist(listOfDataFrames)),
  replications = 100, order = "relative", 
  columns=c('test','replications', 'elapsed','relative')
  ) 

                  test replications elapsed relative
4 data.table_rbindlist          100    0.11    1.000
1              do.call          100    9.39   85.364
2      plyr_rbind.fill          100   12.08  109.818
3           plyr_ldply          100   15.14  137.636

3
এর জন্য আপনাকে অনেক ধন্যবাদ - আমি আমার চুলগুলি টানছিলাম কারণ আমার ডেটা সেটগুলি ldplyবহুগুণ লম্বা, গলিত ডেটা ফ্রেমের আইংয়ের জন্য খুব বড় হয়ে উঠছিল। যাইহোক, আপনার rbindlistপরামর্শটি ব্যবহার করে আমি একটি অবিশ্বাস্য স্পিডআপ পেয়েছি ।
কারাটস্নোম্যাচাইন

11
সম্পূর্ণতার জন্য আরও একটি: dplyr::rbind_all(listOfDataFrames)কৌশলটিও করবে।
andyteucher

2
rbindlistকলাম দ্বারা ডেটা ফ্রেম সংযোজন এর সমতুল্য কি আছে ? সিবাইন্ডলিস্টের মতো কিছু?
rafa.pereira

2
@ rafa.pereira একটি সাম্প্রতিক বৈশিষ্ট্য অনুরোধ রইল
হেনরিক

আমি আমার চুলগুলিও টানছিলাম কারণ do.call()18 ঘন্টা ধরে ডেটা ফ্রেমের তালিকায় ছিল এবং এখনও শেষ হয়নি, আপনাকে ধন্যবাদ !!!
গ্রিম ফ্রস্ট

74

বেঁধে-চক্রান্ত

কোড:

library(microbenchmark)

dflist <- vector(length=10,mode="list")
for(i in 1:100)
{
  dflist[[i]] <- data.frame(a=runif(n=260),b=runif(n=260),
                            c=rep(LETTERS,10),d=rep(LETTERS,10))
}


mb <- microbenchmark(
plyr::rbind.fill(dflist),
dplyr::bind_rows(dflist),
data.table::rbindlist(dflist),
plyr::ldply(dflist,data.frame),
do.call("rbind",dflist),
times=1000)

ggplot2::autoplot(mb)

সেশন:

R version 3.3.0 (2016-05-03)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

> packageVersion("plyr")
[1]1.8.4> packageVersion("dplyr")
[1]0.5.0> packageVersion("data.table")
[1]1.9.6

আপডেট : 31-জানুয়ারী -2018 পুনরায় চালু। একই কম্পিউটারে রান। প্যাকেজগুলির নতুন সংস্করণ। বীজ প্রেমীদের জন্য যোগ করা বীজ।

এখানে চিত্র বর্ণনা লিখুন

set.seed(21)
library(microbenchmark)

dflist <- vector(length=10,mode="list")
for(i in 1:100)
{
  dflist[[i]] <- data.frame(a=runif(n=260),b=runif(n=260),
                            c=rep(LETTERS,10),d=rep(LETTERS,10))
}


mb <- microbenchmark(
  plyr::rbind.fill(dflist),
  dplyr::bind_rows(dflist),
  data.table::rbindlist(dflist),
  plyr::ldply(dflist,data.frame),
  do.call("rbind",dflist),
  times=1000)

ggplot2::autoplot(mb)+theme_bw()


R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

> packageVersion("plyr")
[1]1.8.4> packageVersion("dplyr")
[1]0.7.2> packageVersion("data.table")
[1]1.10.4

আপডেট : 06-অগস্ট -2018 পুনরায়।

এখানে চিত্র বর্ণনা লিখুন

set.seed(21)
library(microbenchmark)

dflist <- vector(length=10,mode="list")
for(i in 1:100)
{
  dflist[[i]] <- data.frame(a=runif(n=260),b=runif(n=260),
                            c=rep(LETTERS,10),d=rep(LETTERS,10))
}


mb <- microbenchmark(
  plyr::rbind.fill(dflist),
  dplyr::bind_rows(dflist),
  data.table::rbindlist(dflist),
  plyr::ldply(dflist,data.frame),
  do.call("rbind",dflist),
  purrr::map_df(dflist,dplyr::bind_rows),
  times=1000)

ggplot2::autoplot(mb)+theme_bw()

R version 3.6.0 (2019-04-26)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 18.04.2 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

packageVersion("plyr")
packageVersion("dplyr")
packageVersion("data.table")
packageVersion("purrr")

>> packageVersion("plyr")
[1]1.8.4>> packageVersion("dplyr")
[1]0.8.3>> packageVersion("data.table")
[1]1.12.2>> packageVersion("purrr")
[1]0.3.2

2
এটি একটি দুর্দান্ত উত্তর। আমি একই জিনিসটি চালিয়েছি (একই ওএস, একই প্যাকেজগুলি, বিভিন্ন র্যান্ডমাইজেশন কারণ আপনি না set.seed) তবে খারাপ অবস্থার পারফরম্যান্সে কিছু পার্থক্য দেখেছি। rbindlistআমার ফলাফলগুলিতে সবচেয়ে খারাপ-মামলার পাশাপাশি সেরা টিপিক্যাল-
কেসটি ছিল

48

ভিতরেও bind_rows(x, ...)আছে dplyr

> system.time({ df.Base <- do.call("rbind", listOfDataFrames) })
   user  system elapsed 
   0.08    0.00    0.07 
> 
> system.time({ df.dplyr <- as.data.frame(bind_rows(listOfDataFrames)) })
   user  system elapsed 
   0.01    0.00    0.02 
> 
> identical(df.Base, df.dplyr)
[1] TRUE

প্রযুক্তিগতভাবে বলতে গেলে আপনার as.data.frame এর দরকার নেই - এটি যা কেবলমাত্র একটি ডেটা.ফ্রেমে তৈরি করে, যেমন একটি টেবিল_ডিএফ (বিপরীতে)
ব্যবহারকারী 1617979

14

এটি করার আরও একটি উপায় এখানে রয়েছে (কেবলমাত্র উত্তরের সাথে এটি যুক্ত করা কারণ reduceএটি একটি কার্যকর কার্যকরী সরঞ্জাম যা প্রায়শই লুপগুলির প্রতিস্থাপন হিসাবে উপেক্ষা করা হয় this এই বিশেষ ক্ষেত্রে, এগুলির কোনওটিই do.call এর চেয়ে উল্লেখযোগ্যভাবে দ্রুত নয়)

বেস বেস ব্যবহার:

df <- Reduce(rbind, listOfDataFrames)

বা, পরিপাটি ব্যবহার করে:

library(tidyverse) # or, library(dplyr); library(purrr)
df <- listOfDataFrames %>% reduce(bind_rows)

11

কীভাবে এটি পরিপাটি করা উচিত:

df.dplyr.purrr <- listOfDataFrames %>% map_df(bind_rows)

3
আপনি mapযদি bind_rowsডেটাফ্রেমগুলির একটি তালিকা নিতে পারেন তবে আপনি কেন ব্যবহার করবেন?
see24

9

যারা সাম্প্রতিক উত্তরগুলির কয়েকটি তুলনা করতে চান তাদের জন্য একটি আপডেট ভিজ্যুয়াল (আমি পিউরিয়ারকে ডিপ্লাইর সলিউশনের সাথে তুলনা করতে চেয়েছিলাম)। মূলত আমি @TheVTM এবং @rmf থেকে উত্তরগুলি একত্রিত করেছি।

এখানে চিত্র বর্ণনা লিখুন

কোড:

library(microbenchmark)
library(data.table)
library(tidyverse)

dflist <- vector(length=10,mode="list")
for(i in 1:100)
{
  dflist[[i]] <- data.frame(a=runif(n=260),b=runif(n=260),
                            c=rep(LETTERS,10),d=rep(LETTERS,10))
}


mb <- microbenchmark(
  dplyr::bind_rows(dflist),
  data.table::rbindlist(dflist),
  purrr::map_df(dflist, bind_rows),
  do.call("rbind",dflist),
  times=500)

ggplot2::autoplot(mb)

সেশন তথ্য:

sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

প্যাকেজ সংস্করণ:

> packageVersion("tidyverse")
[1]1.1.1> packageVersion("data.table")
[1]1.10.0

7

সমাধানগুলির সাথে সমাধানগুলি কেবল data.tableঅনুপস্থিত রয়েছে তা হল শনাক্তকারী কলামটি থেকে তালিকার কোন ডাটাফ্রেমটি তালিকা থেকে ডেটা আসছে তা জানা to

এটার মতো কিছু:

df_id <- data.table::rbindlist(listOfDataFrames, idcol = TRUE)

idcolপ্যারামিটারটি কলাম (যোগ .id) dataframe তালিকা উপস্থিত রয়েছে উৎপত্তি চিহ্নিতকরণের। ফলাফলটি এরকম কোনও কিছুর দিকে নজর রাখবে:

.id a         b           c
1   u   -0.05315128 -1.31975849 
1   b   -1.00404849 1.15257952  
1   y   1.17478229  -0.91043925 
1   q   -1.65488899 0.05846295  
1   c   -1.43730524 0.95245909  
1   b   0.56434313  0.93813197  
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.