একাধিক কলাম (গুলি) দ্বারা ডেটাফ্রেমকে কীভাবে সাজানো যায়


1316

আমি একাধিক কলাম দ্বারা একটি ডেটা ফ্রেম বাছাই করতে চাই। উদাহরণস্বরূপ, নীচে ডেটা ফ্রেম দিয়ে আমি কলামটি z(উতরাই) বাছাই করতে চাই তারপরে কলাম b(আরোহণ) দ্বারা:

dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
dd
    b x y z
1  Hi A 8 1
2 Med D 3 1
3  Hi A 9 1
4 Low C 9 2

উত্তর:


1624

order()অ্যাড-অন সরঞ্জামগুলি অবলম্বন না করে আপনি সরাসরি ফাংশনটি ব্যবহার করতে পারেন - এই সহজ উত্তরটি দেখুন যা example(order)কোডের উপরের অংশ থেকে সরাসরি একটি কৌশল ব্যবহার করে :

R> dd[with(dd, order(-z, b)), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

কিছু 2+ বছর পরে সম্পাদনা করুন: কলাম সূচক দ্বারা এটি কীভাবে করা যায় তা সবেমাত্র জিজ্ঞাসা করা হয়েছিল। উত্তরটি হ'ল order()ফাংশনে পছন্দসই বাছাইকরণ কলাম (গুলি) সরবরাহ করা :

R> dd[order(-dd[,4], dd[,1]), ]
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1
R> 

কলামটির নাম ব্যবহার না করে (এবং with()সহজ / আরও সরাসরি অ্যাক্সেসের জন্য)।


@ ডার্ক এডেলবুয়েটেল কি ম্যাট্রিক্সের জন্য একই রকম সহজ পদ্ধতি আছে?
জোটা

14
একইভাবে কাজ করা উচিত, তবে আপনি ব্যবহার করতে পারবেন না withM <- matrix(c(1,2,2,2,3,6,4,5), 4, 2, byrow=FALSE, dimnames=list(NULL, c("a","b")))একটি ম্যাট্রিক্স তৈরি করার চেষ্টা করুন M, তারপরে M[order(M[,"a"],-M[,"b"]),]এটি দুটি কলামে অর্ডার করতে ব্যবহার করুন।
ডার্ক এডেলবুয়েটেল

4
যথেষ্ট সহজ: dd[ order(-dd[,4], dd[,1]), ]তবে withনাম ভিত্তিক সাবসেটিংয়ের জন্য ব্যবহার করতে পারবেন না ।
ডার্ক এডেলবুয়েটেল

18
দ্বিতীয় উদাহরণটি চালানোর সময় আমার "অকারি অপারেটরের কাছে অবৈধ যুক্তি" ত্রুটি রয়েছে।
নাইলগুন

21
"আনারি অপারেটরের কাছে অবৈধ যুক্তি" ত্রুটিটি ঘটে যখন আপনি একটি অক্ষর কলাম দিয়ে বিয়োগ ব্যবহার করেন। xtfrmউদাহরণস্বরূপ কলামটি মোড়ানো দ্বারা এটি সমাধান করুন dd[ order(-xtfrm(dd[,4]), dd[,1]), ]
রিচি কটন

476

আপনার পছন্দ

  • order থেকে base
  • arrange থেকে dplyr
  • setorderএবং setordervথেকেdata.table
  • arrange থেকে plyr
  • sort থেকে taRifx
  • orderBy থেকে doBy
  • sortData থেকে Deducer

কোনও সময় নির্ভরতা না থাকলে আপনার বেশিরভাগ সময় সমাধান dplyrবা data.tableসমাধানগুলি ব্যবহার করা উচিত , এক্ষেত্রে ব্যবহার base::order


আমি সম্প্রতি CRAN প্যাকেজে सॉर्ट.ডাটা.ফ্রেম যুক্ত করেছি, এখানে আলোচিত হিসাবে এটি শ্রেণি সামঞ্জস্যপূর্ণ: সারণি.ডাটা.ফ্রেমের জন্য জেনেরিক / পদ্ধতির ধারাবাহিকতা তৈরি করার সর্বোত্তম উপায়?

অতএব, ডেটা.ফ্রেমে ডিডি দেওয়া, আপনি নিম্নলিখিত হিসাবে বাছাই করতে পারেন:

dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
library(taRifx)
sort(dd, f= ~ -z + b )

আপনি যদি এই ফাংশনের মূল লেখকদের একজন হন তবে দয়া করে আমার সাথে যোগাযোগ করুন। জনসাধারণের ডোমেনাইনেস হিসাবে আলোচনা এখানে: http://chat.stackoverflow.com/transcript/message/1094290#1094290


উপরের থ্রেডে হ্যাডলি যেভাবে নির্দেশ করেছেন সেভাবে আপনি arrange()ফাংশনটি ব্যবহার করতে পারেন plyr:

library(plyr)
arrange(dd,desc(z),b)

বেঞ্চমার্কস: নোট করুন যে আমি একটি নতুন আর সেশনে প্রতিটি প্যাকেজ লোড করেছি যেহেতু প্রচুর দ্বন্দ্ব ছিল। বিশেষ করে ডোবাই প্যাকেজ লোড করার ফলে sort"নিম্নলিখিত বিষয়গুলি (গুলি) 'x (অবস্থান 17)' থেকে মুখোশযুক্ত: বি, এক্স, ওয়াই, জেড", এবং sort.data.frameকেভিন রাইট বা ট্যারিফ্যাক্স প্যাকেজ থেকে ডিডুসার প্যাকেজ ওভাররাইটগুলি লোড করে ।

#Load each time
dd <- data.frame(b = factor(c("Hi", "Med", "Hi", "Low"), 
      levels = c("Low", "Med", "Hi"), ordered = TRUE),
      x = c("A", "D", "A", "C"), y = c(8, 3, 9, 9),
      z = c(1, 1, 1, 2))
library(microbenchmark)

# Reload R between benchmarks
microbenchmark(dd[with(dd, order(-z, b)), ] ,
    dd[order(-dd$z, dd$b),],
    times=1000
)

মধ্যযুগীয় সময়:

dd[with(dd, order(-z, b)), ] 778

dd[order(-dd$z, dd$b),] 788

library(taRifx)
microbenchmark(sort(dd, f= ~-z+b ),times=1000)

মধ্যযুগীয় সময়: 1,567

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=1000)

মধ্যযুগীয় সময়: 862

library(doBy)
microbenchmark(orderBy(~-z+b, data=dd),times=1000)

মধ্যযুগীয় সময়: 1,694

নোট করুন যে প্যাকেজটি লোড করতে ডোবাই বেশ ভাল সময় নেয়।

library(Deducer)
microbenchmark(sortData(dd,c("z","b"),increasing= c(FALSE,TRUE)),times=1000)

ডিডুসার লোড করা যায়নি। জেজিআর কনসোল প্রয়োজন।

esort <- function(x, sortvar, ...) {
attach(x)
x <- x[with(x,order(sortvar,...)),]
return(x)
detach(x)
}

microbenchmark(esort(dd, -z, b),times=1000)

সংযুক্তি / বিচ্ছিন্নতার কারণে মাইক্রোবেঞ্চমার্কের সাথে সামঞ্জস্যপূর্ণ বলে মনে হয় না।


m <- microbenchmark(
  arrange(dd,desc(z),b),
  sort(dd, f= ~-z+b ),
  dd[with(dd, order(-z, b)), ] ,
  dd[order(-dd$z, dd$b),],
  times=1000
  )

uq <- function(x) { fivenum(x)[4]}  
lq <- function(x) { fivenum(x)[2]}

y_min <- 0 # min(by(m$time,m$expr,lq))
y_max <- max(by(m$time,m$expr,uq)) * 1.05

p <- ggplot(m,aes(x=expr,y=time)) + coord_cartesian(ylim = c( y_min , y_max )) 
p + stat_summary(fun.y=median,fun.ymin = lq, fun.ymax = uq, aes(fill=expr))

মাইক্রোবেঞ্চমার্ক প্লট

(রেখাগুলি নিম্ন চতুর্থাংশ থেকে উপরের চতুর্দিকে বিস্তৃত হয়, বিন্দুটি মাঝারি হয়)


এই ফলাফল দেওয়া এবং সরলতা বনাম গতি ওজনের, আমি নড়া দিতে হবে চাই arrangeমধ্যে plyrপ্যাকেজ । এটিতে একটি সরল বাক্য গঠন রয়েছে এবং তবুও প্রায় তাদের দ্রবীভূত যন্ত্রে বেস আর কমান্ডগুলির মতো দ্রুত গতি রয়েছে। সাধারণত উজ্জ্বল হ্যাডলি উইকহ্যাম কাজ। এটির সাথে আমার একমাত্র গ্রিপ এটি মানক আর নামকরণটি ভেঙে দেয় যেখানে বাছাই করা বস্তুগুলি ডেকে sort(object)আনে, তবে আমি বুঝতে পারি যে উপরে লিঙ্কিত প্রশ্নে আলোচিত ইস্যুগুলির কারণে হ্যাডলি কেন সেভাবে এটি করেছিল।


3
উপরের ggplot2 মাইক্রোব্যাঙ্কমার্ক ফাংশন এখন হিসাবে উপলব্ধ taRifx::autoplot.microbenchmark
এরি বি ফ্রেডম্যান

@ আরিবি.ফ্রিডম্যান y অক্ষরের অন্তরগুলি কী / কী পরিমাণ?
nnot101

@ naught101 y অক্ষটি 0 থেকে শুরু হয় Sc স্কেলটি মাইক্রোসেকেন্ড হতে হবে।
এরি বি ফ্রেডম্যান

2
bনমুনা অনুসারে বাছাই করা হয়েছে তা দেখুন AME ডিফল্টটি আরোহণের দ্বারা বাছাই করা হয়, সুতরাং আপনি কেবল এটিতে গুটিয়ে রাখবেন না desc। উভয় আরোহী: arrange(dd,z,b)। উভয় নিম্নক্রম: arrange(dd,desc(z),desc(b))
এরি বি ফ্রেডম্যান

2
অনুসারে ?arrange: "# দ্রষ্টব্য: প্লেয়ার ফাংশন সারি.নামগুলি সংরক্ষণ করে না"। arrange()যদি কেউ রাখতে চান তবে এটি দুর্দান্ত ফাংশনটিকে সাবঅপটিমাল করে তোলে row.names
ল্যান্ড্রোনি 16

148

ডার্কের উত্তরটি দুর্দান্ত। এটি data.frameএস এবং এসকে সূচীকরণের জন্য ব্যবহৃত সিনট্যাক্সের মূল পার্থক্যটিকেও হাইলাইট করে data.table:

## The data.frame way
dd[with(dd, order(-z, b)), ]

## The data.table way: (7 fewer characters, but that's not the important bit)
dd[order(-z, b)]

দুটি কলের মধ্যে পার্থক্যটি সামান্য, তবে এটির গুরুত্বপূর্ণ পরিণতি হতে পারে। বিশেষত যদি আপনি প্রোডাকশন কোডটি লিখেন এবং / বা আপনার গবেষণায় যথার্থতার সাথে উদ্বিগ্ন হন তবে পরিবর্তনশীল নামের অপ্রয়োজনীয় পুনরাবৃত্তি এড়ানো ভাল। data.table আপনাকে এটি করতে সহায়তা করে।

চলক নামের পুনরাবৃত্তি আপনাকে কীভাবে সমস্যায় ফেলতে পারে তার উদাহরণ এখানে:

আসুন আমরা ডার্কের উত্তর থেকে প্রসঙ্গটি পরিবর্তন করি এবং বলি এটি একটি বৃহত প্রকল্পের অংশ যেখানে সেখানে প্রচুর অবজেক্টের নাম রয়েছে এবং সেগুলি দীর্ঘ এবং অর্থবহ; পরিবর্তে ddএটি বলা হয় quarterlyreport। ইহা হতে পারে :

quarterlyreport[with(quarterlyreport,order(-z,b)),]

আচ্ছা ঠিক আছে. কিছুতেই ভুল হয়নি। এরপরে আপনার বস আপনাকে শেষ কোয়ার্টারের প্রতিবেদনে অন্তর্ভুক্ত করতে বলে। আপনি lastquarterlyreportবিভিন্ন স্থানে কোনও বস্তু যুক্ত করে কোনও কোনওরকম (পৃথিবীতে কীভাবে?) আপনি নিজের কোডটি দিয়ে চলেছেন আপনি এটিকে শেষ করেছেন:

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

এটি আপনি বোঝাতে চেয়েছেন তা নয় তবে আপনি এটি স্পষ্ট করেননি কারণ আপনি এটি দ্রুত করেছিলেন এবং এটি একই কোডের একটি পৃষ্ঠায় বাসা বেঁধেছে। কোডটি পড়ে না (কোনও সতর্কতা এবং কোনও ত্রুটি নেই) কারণ আর মনে করে যে এটি আপনি যা বোঝাতে চেয়েছিলেন তা। আপনি আশা করতেন যে কেউ আপনার প্রতিবেদনটি পড়বে সে এটি দাগী করে, তবে তারা তা করবে না। আপনি যদি প্রোগ্রামিং ভাষা নিয়ে অনেক বেশি কাজ করেন তবে এই পরিস্থিতিটি সবার জানা থাকতে পারে। এটি একটি "টাইপো" ছিল আপনি বলবেন। আমি "টাইপো" ঠিক করব আপনি আপনার বসকে বলবেন।

ইন data.tableআমরা ভালো ক্ষুদ্র বিবরণ সম্পর্কে উদ্বিগ্ন হয়েছে। সুতরাং আমরা ভেরিয়েবলের নাম দু'বার টাইপ করা এড়াতে সহজ কিছু করেছি। খুব সহজ কিছু। ইতিমধ্যে, স্বয়ংক্রিয়ভাবে iফ্রেমের মধ্যে মূল্যায়ন করা ddহয়। আপনার মোটেই দরকার নেই with()

পরিবর্তে

dd[with(dd, order(-z, b)), ]

এটা শুধু

dd[order(-z, b)]

এবং পরিবর্তে

quarterlyreport[with(lastquarterlyreport,order(-z,b)),]

এটা শুধু

quarterlyreport[order(-z,b)]

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


9
+1 এটি একটি দুর্দান্ত পয়েন্ট এবং এটি আর এর বাক্য গঠন সম্পর্কে বিস্তারিত পেয়েছে যা প্রায়শই আমাকে বিরক্ত করে তোলে। আমি কখনও কখনও subset()কেবল একই কলের মধ্যে একই জিনিসটি বার বার উল্লেখ করা এড়াতে কেবল ব্যবহার করি ।
জোশ ও'ব্রায়েন

2
@ naught101 ডেটা.এফএইউএল 1.9 এর উত্তর দেয় কি?
ম্যাট ডাওল

5
আমার ধারণা আপনি setorderএখানেও নতুন ফাংশন যুক্ত করতে পারেন , এই থ্রেডটি হ'ল যেখানে আমরা সমস্ত orderধরণের ডুপ প্রেরণ করি ।
ডেভিড আরেনবার্গ

125

এখানে প্রচুর চমত্কার উত্তর রয়েছে, তবে ডিপি্লায়ার একমাত্র সিনট্যাক্স দেয় যা আমি দ্রুত এবং সহজেই মনে রাখতে পারি (এবং এখন খুব ঘন ঘন ব্যবহার করি):

library(dplyr)
# sort mtcars by mpg, ascending... use desc(mpg) for descending
arrange(mtcars, mpg)
# sort mtcars first by mpg, then by cyl, then by wt)
arrange(mtcars , mpg, cyl, wt)

ওপির সমস্যার জন্য:

arrange(dd, desc(z),  b)

    b x y z
1 Low C 9 2
2 Med D 3 1
3  Hi A 8 1
4  Hi A 9 1

2
যখন আমার কলামগুলি ফ্যাক্টর (বা এর মতো কিছু) টাইপ করা হবে তখন গৃহীত উত্তরটি কাজ করে না এবং আমি এই ফ্যাক্টর কলামটির জন্য ক্রমবর্ধমান ফ্যাশনকে ক্রমবর্ধমান ফ্যাশনে পূর্ণসংখ্যা কলাম অনুসারে বাছাই করতে চাই। তবে এটি ঠিক কাজ করে! ধন্যবাদ!
সাহেল গোধন

10
"শুধু" কেন? আমি ডেটা টেবিলের dd[order(-z, b)]ব্যবহার এবং মনে রাখার পক্ষে খুব সহজ।
ম্যাট ডাউল

2
সম্মত হন, এই দুটি পদ্ধতির মধ্যে খুব বেশি কিছু নেই এবং data.tableএটি Rঅন্য অনেক উপায়েও একটি বিশাল অবদান । আমি মনে করি আমার জন্য, এটি হতে পারে যে এই ক্ষেত্রে একটি কম বন্ধনী (বা এক কম ধরণের বন্ধনী) কম রাখার ফলে জ্ঞানীয় লোডটি সবেমাত্র অনুধাবনযোগ্য পরিমাণ দ্বারা হ্রাস পেয়েছে।
বেন

7
আমার জন্য এটি arrange()সম্পূর্ণরূপে ঘোষণামূলক যে সত্যে নেমে আসে , dd[order(-z, b)]তা নয়।
মুললেফা

83

আর প্যাকেজ data.tableউভয় উপলব্ধ ফাস্ট এবং মেমরির দক্ষ ক্রম data.tables একটি সহজবোধ্য সিনট্যাক্স (ক অংশ যার ম্যাট বেশ চমত্কারভাবে তুলে ধরা হয়েছে সঙ্গে তার উত্তরে )। তখন থেকে অনেক উন্নতি হয়েছে এবং একটি নতুন ফাংশনও setorder()রয়েছে। থেকে v1.9.5+, ডেটা.ফ্রেমগুলিরsetorder() সাথেও কাজ করে ।

প্রথমত, আমরা যথেষ্ট পরিমাণে একটি ডেটাসেট তৈরি করব এবং অন্যান্য উত্তর থেকে উল্লিখিত বিভিন্ন পদ্ধতির মাপদণ্ড করব এবং তারপরে ডেটা.ট্যাবলের বৈশিষ্ট্যগুলি তালিকাবদ্ধ করব

ডেটা:

require(plyr)
require(doBy)
require(data.table)
require(dplyr)
require(taRifx)

set.seed(45L)
dat = data.frame(b = as.factor(sample(c("Hi", "Med", "Low"), 1e8, TRUE)),
                 x = sample(c("A", "D", "C"), 1e8, TRUE),
                 y = sample(100, 1e8, TRUE),
                 z = sample(5, 1e8, TRUE), 
                 stringsAsFactors = FALSE)

benchmarks:

রিপোর্ট করা সময়গুলি system.time(...)নীচে প্রদর্শিত এই ফাংশনগুলিতে চালানো থেকে শুরু করে। সময়গুলি নীচে সারণী করা হয়েছে (দ্রুততম থেকে দ্রুততমের ক্রমে)।

orderBy( ~ -z + b, data = dat)     ## doBy
plyr::arrange(dat, desc(z), b)     ## plyr
arrange(dat, desc(z), b)           ## dplyr
sort(dat, f = ~ -z + b)            ## taRifx
dat[with(dat, order(-z, b)), ]     ## base R

# convert to data.table, by reference
setDT(dat)

dat[order(-z, b)]                  ## data.table, base R like syntax
setorder(dat, -z, b)               ## data.table, using setorder()
                                   ## setorder() now also works with data.frames 

# R-session memory usage (BEFORE) = ~2GB (size of 'dat')
# ------------------------------------------------------------
# Package      function    Time (s)  Peak memory   Memory used
# ------------------------------------------------------------
# doBy          orderBy      409.7        6.7 GB        4.7 GB
# taRifx           sort      400.8        6.7 GB        4.7 GB
# plyr          arrange      318.8        5.6 GB        3.6 GB 
# base R          order      299.0        5.6 GB        3.6 GB
# dplyr         arrange       62.7        4.2 GB        2.2 GB
# ------------------------------------------------------------
# data.table      order        6.2        4.2 GB        2.2 GB
# data.table   setorder        4.5        2.4 GB        0.4 GB
# ------------------------------------------------------------
  • data.tableএর DT[order(...)]সিনট্যাক্স ছিল ~ 10x অন্যান্য পদ্ধতি (এর দ্রুততম তুলনায় দ্রুততর dplyr,) যখন যেমন মেমরি একই পরিমাণ গ্রাসকারী dplyr

  • data.tableএর setorder()ছিল ~ 14x দ্রুত অন্যান্য পদ্ধতি (এর দ্রুততম চেয়ে dplyr,) সময় নিচ্ছে মাত্র 0.4GB অতিরিক্ত মেমরিdatএখন আমাদের প্রয়োজনীয় ক্রমে রয়েছে (যেমন এটি রেফারেন্স দ্বারা আপডেট হয়)।

ডেটা টেবিল বৈশিষ্ট্য:

দ্রুততা:

  • ডেটা টেবিলের অর্ডারিং অত্যন্ত দ্রুত কারণ এটি র‌্যাডিক্স ক্রম প্রয়োগ করে ।

  • ডেটা টেবিলের দ্রুত অর্ডারওDT[order(...)] ব্যবহার করতে সিনট্যাক্সটি অভ্যন্তরীণভাবে অনুকূলিত হয়েছে । আপনি পরিচিত বেস আর সিনট্যাক্স ব্যবহার চালিয়ে যেতে পারেন তবে প্রক্রিয়াটি গতি বাড়িয়ে তুলুন (এবং কম স্মৃতি ব্যবহার করুন)।

স্মৃতি:

  • সময়ের সর্বাধিক, আমরা আসল প্রয়োজন হয় না data.frame বা data.table পুনঃক্রমবিন্যাস পরে। এটি হ'ল, আমরা সাধারণত ফলাফলটিকে একই জিনিসটিতে ফিরিয়ে দেয়, উদাহরণস্বরূপ:

    DF <- DF[order(...)]

    সমস্যাটি হ'ল এর জন্য কমপক্ষে দুবার (2x) আসল বস্তুর মেমরির প্রয়োজন। হতে মেমরির দক্ষ , data.table তাই একটি ফাংশন প্রদান করে setorder()

    setorder()reorders data.tables by reference ( ইন-জায়গা ), কোন অতিরিক্ত কপি না করে। এটি কেবলমাত্র একটি কলামের আকারের সমান অতিরিক্ত মেমরি ব্যবহার করে।

অন্যান্য বৈশিষ্ট্য:

  1. এটি সমর্থন করে integer, logical, numeric, characterএবং এমনকি bit64::integer64ধরনের।

    লক্ষ্য করুন factor, Date, POSIXctইত্যাদি .. শ্রেণীর সব integer/ numericধরনের অতিরিক্ত বৈশিষ্ট্যাবলী সঙ্গে নীচে এবং সেইজন্য পাশাপাশি সমর্থিত।

  2. বেস আরে, আমরা -কলামটিকে ক্রমবর্ধমান ক্রমে সাজানোর জন্য একটি অক্ষর ভেক্টর ব্যবহার করতে পারি না । পরিবর্তে আমাদের ব্যবহার করতে হবে -xtfrm(.)

    যাইহোক, ডেটা.টিটেবেলে , আমরা কেবল যেমন করতে পারি, উদাহরণস্বরূপ, dat[order(-x)]বা setorder(dat, -x)


ডেটা.টিবেল সম্পর্কে এই শিক্ষামূলক উত্তরের জন্য ধন্যবাদ। যদিও, "পিক মেমরি" কী এবং আপনি এটি কীভাবে গণনা করেছেন তা আমি বুঝতে পারি না। আপনি দয়া করে ব্যাখ্যা করতে পারেন? ধন্যবাদ !
জুলিয়ান নাভারে

আমি ইনস্ট্রুমেন্টস -> বরাদ্দ ব্যবহার করেছি এবং "সমস্ত হিপ এবং বরাদ্দ ভিএম" আকারের প্রতিবেদন করেছি।
অরুণ

2
আপনার মন্তব্যটিতে অরুন ইনস্ট্রুমেন্টস লিঙ্কটি মারা গেছে। একটি আপডেট পোস্ট করতে যত্নশীল?
মাইকেলচিরিকো


73

সঙ্গে এই (খুব সহায়ক) ফাংশন কেভিন রাইট , আর উইকি এর টিপস বিভাগে পোস্ট, এই সহজে এটা করা যায়।

sort(dd,by = ~ -z + b)
#     b x y z
# 4 Low C 9 2
# 2 Med D 3 1
# 1  Hi A 8 1
# 3  Hi A 9 1

2
এই ফাংশনটিতে ব্যবহৃত অ্যালগরিদমের বেঞ্চমার্কিংয়ের জন্য আমার উত্তর দেখুন।
এরি বি ফ্রেডম্যান


39

ধরুন আপনার একটি রয়েছে data.frame Aএবং আপনি এটি xসাজানো ক্রম নামক কলামটি ব্যবহার করে বাছাই করতে চান । বাছাই করা কল করুনdata.frame newdata

newdata <- A[order(-A$x),]

আপনি যদি আরোহী ক্রম চান তবে "-"কিছুই দিয়ে প্রতিস্থাপন করুন । আপনার মতো কিছু থাকতে পারে

newdata <- A[order(-A$x, A$y, -A$z),]

যেখানে xএবং zকিছু কলাম রয়েছে data.frame A। এর অর্থ সাজানো, আরোহণ এবং উতরাই data.frame Aদ্বারা সাজানো।xyz


32

যদি এসকিউএল আপনার কাছে স্বাভাবিকভাবে আসে তবে sqldfপ্যাকেজ ORDER BYকোডডের উদ্দেশ্যে হ্যান্ডেল করে ।


7
এমজেএম, এই প্যাকেজটি দেখানোর জন্য ধন্যবাদ। এটি অবিশ্বাস্যরূপে নমনীয় এবং কারণ আমার অর্ধেক কাজ ইতিমধ্যে এসকিউএল ডেটাবেসগুলি থেকে টানতে সম্পন্ন হয়েছে যা স্বজ্ঞাত সিন্টেক্সের চেয়ে আর এর চেয়ে কম শেখার চেয়ে সহজ easier
ব্র্যান্ডন বার্টেলসেন

31

বিকল্পভাবে, প্যাকেজ ডিডুসার ব্যবহার করে

library(Deducer)
dd<- sortData(dd,c("z","b"),increasing= c(FALSE,TRUE))

19

কীভাবে প্রোগ্রামটিমেটিকভাবে বাছাই করা যায় তার জন্য ওপিতে যুক্ত একটি মন্তব্যের জবাবে:

ব্যবহার dplyrএবংdata.table

library(dplyr)
library(data.table)

dplyr

কেবল ব্যবহার করুন arrange_, এটির জন্য আদর্শ মূল্যায়ন সংস্করণ arrange

df1 <- tbl_df(iris)
#using strings or formula
arrange_(df1, c('Petal.Length', 'Petal.Width'))
arrange_(df1, ~Petal.Length, ~Petal.Width)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.4         3.9          1.3         0.4  setosa
7           5.5         3.5          1.3         0.2  setosa
8           4.4         3.0          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...


#Or using a variable
sortBy <- c('Petal.Length', 'Petal.Width')
arrange_(df1, .dots = sortBy)
    Source: local data frame [150 x 5]

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          (dbl)       (dbl)        (dbl)       (dbl)  (fctr)
1           4.6         3.6          1.0         0.2  setosa
2           4.3         3.0          1.1         0.1  setosa
3           5.8         4.0          1.2         0.2  setosa
4           5.0         3.2          1.2         0.2  setosa
5           4.7         3.2          1.3         0.2  setosa
6           5.5         3.5          1.3         0.2  setosa
7           4.4         3.0          1.3         0.2  setosa
8           4.4         3.2          1.3         0.2  setosa
9           5.0         3.5          1.3         0.3  setosa
10          4.5         2.3          1.3         0.3  setosa
..          ...         ...          ...         ...     ...

#Doing the same operation except sorting Petal.Length in descending order
sortByDesc <- c('desc(Petal.Length)', 'Petal.Width')
arrange_(df1, .dots = sortByDesc)

আরও তথ্য এখানে: https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html

সূত্রটি ব্যবহার করা আরও ভাল কারণ এটি একটি অভিব্যক্তিটি মূল্যায়নের জন্য পরিবেশকেও ক্যাপচার করে

data.table

dt1 <- data.table(iris) #not really required, as you can work directly on your data.frame
sortBy <- c('Petal.Length', 'Petal.Width')
sortType <- c(-1, 1)
setorderv(dt1, sortBy, sortType)
dt1
     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
  1:          7.7         2.6          6.9         2.3 virginica
  2:          7.7         2.8          6.7         2.0 virginica
  3:          7.7         3.8          6.7         2.2 virginica
  4:          7.6         3.0          6.6         2.1 virginica
  5:          7.9         3.8          6.4         2.0 virginica
 ---                                                            
146:          5.4         3.9          1.3         0.4    setosa
147:          5.8         4.0          1.2         0.2    setosa
148:          5.0         3.2          1.2         0.2    setosa
149:          4.3         3.0          1.1         0.1    setosa
150:          4.6         3.6          1.0         0.2    setosa

18

আমি orderনিম্নলিখিত উদাহরণটি সম্পর্কে শিখেছি যা আমাকে দীর্ঘসময় ধরে বিভ্রান্ত করেছিল:

set.seed(1234)

ID        = 1:10
Age       = round(rnorm(10, 50, 1))
diag      = c("Depression", "Bipolar")
Diagnosis = sample(diag, 10, replace=TRUE)

data = data.frame(ID, Age, Diagnosis)

databyAge = data[order(Age),]
databyAge

একমাত্র কারণ এই উদাহরণে কাজ করে কারণ orderদ্বারা বাছাই করা হয় vector Ageনাম কলাম দ্বারা নয় Ageমধ্যে data frame data

এটি দেখতে read.tableকিছুটা আলাদা কলামের নাম দিয়ে এবং উপরের কোনও ভেক্টর ব্যবহার না করেই অভিন্ন ডেটা ফ্রেম তৈরি করুন :

my.data <- read.table(text = '

  id age  diagnosis
   1  49 Depression
   2  50 Depression
   3  51 Depression
   4  48 Depression
   5  50 Depression
   6  51    Bipolar
   7  49    Bipolar
   8  49    Bipolar
   9  49    Bipolar
  10  49 Depression

', header = TRUE)

উপরের রেখা কাঠামোটি orderআর কাজ করে না কারণ কোনও ভেক্টর নাম নেই age:

databyage = my.data[order(age),]

নীচের লাইনটি কাজ করে কারণ orderকলামে বাছাই ageকরে my.data

databyage = my.data[order(my.data$age),]

আমি ভেবেছিলাম এত দিন ধরে এই উদাহরণে আমি কতটা বিভ্রান্ত হয়ে পড়েছিলাম তা পোস্ট করার উপযুক্ত। এই পোস্টটি যদি থ্রেডের জন্য উপযুক্ত না মনে হয় তবে আমি এটি মুছে ফেলতে পারি।

সম্পাদনা: 13 মে, 2014

নীচে কলামের নাম উল্লেখ না করে প্রতিটি কলাম দ্বারা ডেটা ফ্রেম বাছাইয়ের একটি সাধারণ উপায় way নীচের কোডটি বাম থেকে ডানে বা ডান থেকে বামে কীভাবে বাছাই করতে পারে তা দেখায়। প্রতিটি কলাম সংখ্যাসূচক হলে এটি কাজ করে। আমি একটি অক্ষর কলাম যুক্ত করার চেষ্টা করেছি।

আমি do.callকোডটি এক মাস বা দুই মাস আগে একটি ভিন্ন সাইটে একটি পুরানো পোস্টে পেয়েছি , তবে কেবল ব্যাপক এবং কঠিন অনুসন্ধানের পরে। আমি নিশ্চিত যে আমি এখন এই পোস্টটি স্থানান্তর করতে পারব না। data.frameইন অর্ডার দেওয়ার জন্য বর্তমান থ্রেডটি প্রথম হিট R। সুতরাং, আমি ভেবেছিলাম যে মূল কোডটির আমার প্রসারিত সংস্করণটি কার্যকর do.callহতে পারে।

set.seed(1234)

v1  <- c(0,0,0,0, 0,0,0,0, 1,1,1,1, 1,1,1,1)
v2  <- c(0,0,0,0, 1,1,1,1, 0,0,0,0, 1,1,1,1)
v3  <- c(0,0,1,1, 0,0,1,1, 0,0,1,1, 0,0,1,1)
v4  <- c(0,1,0,1, 0,1,0,1, 0,1,0,1, 0,1,0,1)

df.1 <- data.frame(v1, v2, v3, v4) 
df.1

rdf.1 <- df.1[sample(nrow(df.1), nrow(df.1), replace = FALSE),]
rdf.1

order.rdf.1 <- rdf.1[do.call(order, as.list(rdf.1)),]
order.rdf.1

order.rdf.2 <- rdf.1[do.call(order, rev(as.list(rdf.1))),]
order.rdf.2

rdf.3 <- data.frame(rdf.1$v2, rdf.1$v4, rdf.1$v3, rdf.1$v1) 
rdf.3

order.rdf.3 <- rdf.1[do.call(order, as.list(rdf.3)),]
order.rdf.3

4
এই সিনট্যাক্সটি কাজ করে যদি আপনি আপনার ডেটা কোনও ডেটা.ফ্রেমে পরিবর্তে কোনও ডেটা.ট্যাবেলে সঞ্চয় করেন: require(data.table); my.dt <- data.table(my.data); my.dt[order(age)]এটি কাজ করে কারণ কলামের নামগুলি [] বন্ধনীগুলির ভিতরে উপলব্ধ করা হয়েছে।
ফ্রাঙ্ক

আমি এখানে ডাউনভোটটি প্রয়োজনীয় বলে মনে করি না, তবে আমিও মনে করি না যে এটি হাতের প্রশ্নটিতে অনেক কিছু যুক্ত করেছে , বিশেষত উত্তরগুলির বিদ্যমান সেটগুলি বিবেচনা করে, যার মধ্যে কিছু ইতিমধ্যে data.frameব্যবহারের জন্য এস এর সাথে প্রয়োজনীয়তাটি ক্যাপচার করে withবা $
A5C1D2H2I1M1N2O1R2T1

1
এর জন্য আপভোট do.callমাল্টিকালমনের ডেটা ফ্রেমকে বাছাই করার ছোট্ট কাজ করে। সহজভাবে do.call(sort, mydf.obj)এবং একটি সুন্দর ক্যাসকেড বাছাই করা হবে।
অ্যাডামো

17

ডার্কের উত্তরটি ভাল তবে আপনার যদি চালিয়ে যাওয়ার প্রয়োজন থাকে তবে আপনি সেই ডাটা ফ্রেমের নামে সাজ্টটি আবার প্রয়োগ করতে চাইবেন। উদাহরণ কোড ব্যবহার করে:

dd <- dd[with(dd, order(-z, b)), ] 

13

ডিপ্লিয়ারে অ্যারেঞ্জ () আমার প্রিয় বিকল্প। পাইপ অপারেটরটি ব্যবহার করুন এবং গুরুত্বপূর্ণ থেকে গুরুত্বপূর্ণ দিকটিতে যান aspect

dd1 <- dd %>%
    arrange(z) %>%
    arrange(desc(x))

7

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

সেক্ষেত্রে, do.call()উদ্ধার করতে আসে:

ind <- do.call(what = "order", args = iris[,c(5,1,2,3)])
iris[ind, ]

##        Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
##    14           4.3         3.0          1.1         0.1     setosa
##    9            4.4         2.9          1.4         0.2     setosa
##    39           4.4         3.0          1.3         0.2     setosa
##    43           4.4         3.2          1.3         0.2     setosa
##    42           4.5         2.3          1.3         0.3     setosa
##    4            4.6         3.1          1.5         0.2     setosa
##    48           4.6         3.2          1.4         0.2     setosa
##    7            4.6         3.4          1.4         0.3     setosa
##    (...)

6

সম্পূর্ণতার জন্য: আপনি প্যাকেজ sortByCol()থেকে ফাংশনটি ব্যবহার করতে পারেন BBmisc:

library(BBmisc)
sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE))
    b x y z
4 Low C 9 2
2 Med D 3 1
1  Hi A 8 1
3  Hi A 9 1

পারফরম্যান্স তুলনা:

library(microbenchmark)
microbenchmark(sortByCol(dd, c("z", "b"), asc = c(FALSE, TRUE)), times = 100000)
median 202.878

library(plyr)
microbenchmark(arrange(dd,desc(z),b),times=100000)
median 148.758

microbenchmark(dd[with(dd, order(-z, b)), ], times = 100000)
median 115.872

4
যখন আপনার পদ্ধতিটি সবচেয়ে ধীর হয় তখন পারফরম্যান্স তুলনা যুক্ত করা আশ্চর্যজনক ... যাইহোক 4-সারিতে একটি মানদণ্ড ব্যবহারের মান সন্দেহজনকdata.frame
মাইকেলচিরিকো

5

যেমন অনেক আগে মেকানিকাল কার্ডের চালকরা, প্রথমে সর্বনিম্ন উল্লেখযোগ্য কী অনুসারে বাছাই করুন, তারপরে পরের উল্লেখযোগ্য ইত্যাদি No

 dd <- dd[order(dd$b, decreasing = FALSE),]

এখন আমরা সবচেয়ে গুরুত্বপূর্ণ কী করতে প্রস্তুত do বাছাই স্থিতিশীল, এবং সর্বাধিক উল্লেখযোগ্য কীতে যে কোনও সম্পর্ক ইতিমধ্যে সমাধান করা হয়েছে।

dd <- dd[order(dd$z, decreasing = TRUE),]

এটি দ্রুততম নাও হতে পারে তবে এটি অবশ্যই সহজ এবং নির্ভরযোগ্য



4

আমি এন কলামগুলির জন্য আমার আদেশ প্রক্রিয়াটি স্বয়ংক্রিয় করতে চাইলে আমি উপরের সমাধানগুলির সাথে লড়াই করছি, যার কলামের নামগুলি প্রতিবার আলাদা হতে পারে। psychসোজা পদ্ধতিতে এটি করতে আমি প্যাকেজ থেকে একটি দুর্দান্ত সহায়ক ফাংশন পেয়েছি :

dfOrder(myDf, columnIndices)

যেখানে columnIndicesআপনি এক বা একাধিক কলামের সূচকগুলি ক্রম অনুসারে বাছাই করতে চান। এখানে আরও তথ্য:

'সাইক' প্যাকেজ থেকে dfOrder ফাংশন

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