আমি কীভাবে কোনও আর ডেটা ফ্রেমে একটি নির্দিষ্ট ডুপ্লিকেট রেকর্ড ছাড়া সমস্ত মুছে ফেলব? [বন্ধ]


16

আমার একটি ডেটা ফ্রেম রয়েছে যাতে কিছু নকল আইড থাকে। আমি সর্বাধিক মান দিয়ে সারি রেখে নকল আইডির সাহায্যে রেকর্ডগুলি সরিয়ে দিতে চাই।

সুতরাং এটির মতো কাঠামোর জন্য (অন্যান্য ভেরিয়েবলগুলি প্রদর্শিত হবে না):

id var_1
1 2
1 4
2 1
2 3
3 5
4 2

আমি এটি তৈরি করতে চাই:

id var_1
1 4
2 3
3 5
4 2

আমি অনন্য () এবং সদৃশ () সম্পর্কে জানি, তবে কীভাবে সর্বাধিককরণের নিয়মটি সংযুক্ত করা যায় তা আমি বুঝতে পারি না ...


এটি প্রকৃতপক্ষে স্ট্যাকওভারফ্লোতে হওয়া উচিত কারণ এটি খাঁটি প্রোগ্রামিং সম্পর্কিত একটি কাজ এবং পরিসংখ্যানের সাথে খুব কমই সম্পর্ক রয়েছে
উত্সাহিত

উত্তর:


24

একটি উপায় হ'ল ডেটাটিকে বিপরীত-অনুসারে বাছাই করা এবং duplicatedসমস্ত অনুলিপি ড্রপ করার জন্য ব্যবহার করা। আমার জন্য, এই পদ্ধতিটি ব্যবহারের ক্ষেত্রে প্রয়োগের তুলনায় ধারণাটি সহজতর। আমার মনে হয় এটিও খুব দ্রুত হওয়া উচিত।

# Some data to start with:
z <- data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,5,2))
# id var
#  1   2
#  1   4
#  2   1
#  2   3
#  3   5
#  4   2

# Reverse sort
z <- z[order(z$id, z$var, decreasing=TRUE),]
# id var
#  4   2
#  3   5
#  2   3
#  2   1
#  1   4
#  1   2

# Keep only the first row for each duplicate of z$id; this row will have the
# largest value for z$var
z <- z[!duplicated(z$id),]

# Sort so it looks nice
z <- z[order(z$id, z$var),]
# id var
#  1   4
#  2   3
#  3   5
#  4   2

সম্পাদনা: আমি কেবল বুঝতে পেরেছি যে উপরের বিপরীত সাজানোর এমনকি বাছাই করার প্রয়োজন নেই id। আপনি কেবল z[order(z$var, decreasing=TRUE),]পরিবর্তে ব্যবহার করতে পারেন এবং এটি ঠিক পাশাপাশি কাজ করবে।

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

z <- data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,5,2))

# Sort: id ascending, var descending
z <- z[order(z$id, -z$var),]

# Remove duplicates
z <- z[!duplicated(z$id),]
# id var
#  1   4
#  2   3
#  3   5
#  4   2

1
"স্প্লিট-কম্পিউট-আরবাইন্ড" এর চেয়ে এই পদ্ধতির উল্লেখযোগ্যভাবে দ্রুত। তদতিরিক্ত এটি এটি একাধিক ফ্যাক্টরের উপর গ্রুপিংয়ের অনুমতি দেয়। একটি গ। 650,000 সারি (8, সংকীর্ণ, কলাম) "অর্ডার-সদৃশ" পদ্ধতির 55 সেকেন্ড সময় লেগেছে, বিভক্ত-গণনা-rbind ... 1h15 মিনিট। অবশ্যই যখন সমষ্টিগত গণনা ডুপ্লিকেটগুলি নির্বাচন বা ফিল্টারিং ব্যতীত অন্য হয়, তবে পরবর্তী পদ্ধতির বা অনুরূপ প্লেয়ার-ভিত্তিক পদ্ধতির প্রয়োজন হয়।
এমজেভি

7

আপনি একই আইডি সহ উপাদানগুলি থেকে সর্বাধিক উপাদান নির্বাচন করতে চান। তার জন্য আপনি ddplyপ্যাকেজ প্লেয়ার থেকে ব্যবহার করতে পারেন :

> dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2))
> ddply(dt,.(id),summarise,var_1=max(var))
   id var_1
1  1   4
2  2   3
3  3   4
4  4   2

uniqueএবং duplicatedসদৃশ রেকর্ডগুলি সরিয়ে ফেলার জন্য, আপনার ক্ষেত্রে কেবল ডুপ্লিকেট আইড রয়েছে, রেকর্ড নেই।

আপডেট: অতিরিক্ত ভেরিয়েবলগুলি থাকাকালীন এখানে কোডটি রয়েছে:

> dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2),bu=rnorm(6))
> ddply(dt,~id,function(d)d[which.max(d$var),])

যদি অন্য ভেরিয়েবলগুলি থাকে তবে কীভাবে: আপনি এগুলি কীভাবে বহন করবেন?
অনিকো

আমরা এই জাতীয় প্রশ্নগুলি স্থানান্তর করি না - খুব অল্প লাভের জন্য খুব বেশি ভিড়।

6

বেস-আর সমাধানটি এর splitমধ্যে জড়িত হবে :

z<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2))
do.call(rbind,lapply(split(z,z$id),function(chunk) chunk[which.max(chunk$var),]))

splitতথ্য ফ্রেমটিকে খণ্ডের তালিকায় বিভক্ত করে দেয়, যার উপরে আমরা সর্বাধিক মান সহ একক সারিতে কাটিয়া সঞ্চালন করি এবং তারপরে do.call(rbind,...)একক সারিগুলির তালিকাটিকে আবার একটি ডেটা ফ্রেমে হ্রাস করে।


1
এবং যথারীতি এটি প্লেয়ার সংস্করণের চেয়ে প্রায় 2x গতিযুক্ত।

1
@ এমবিকিউ, হ্যাঁ, স্বভাবতই, তবে আপনি যদি ডিবাগিং ব্যয়কে অন্তর্ভুক্ত করেন তবে সাধারণ তথ্য নির্ধারিত ফলাফলের গতি একই থাকে :) প্লাইর গতির জন্য নয়, স্বচ্ছতা এবং সুবিধার্থে নিবেদিত।
এমপিক্টাস


2
@ এডোয়ার্ডো aveহ'ল lapply+ এর মোড়ক, splitকোডটি পরীক্ষা করুন (-;

1
@ এদুয়ার্দো হ্যাঁ, তবে এটি সমস্ত কারণগুলির মধ্যে ব্যবহারের মাধ্যমে ভেক্টরাইজড বাছাইয়ের এক স্পর্শকাতর সম্ভাবনার কারণে কাজ করে order; আরও সাধারণ সমস্যা splitঅনিবার্য।

5

আমি ব্যবহার পছন্দ করি ave

dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,3,3,4,2))
## use unique if you want to exclude duplicate maxima
unique(subset(dt, var==ave(var, id, FUN=max)))

+1, Ave সম্পর্কে জানতেন না। এটি আর-তে কখন হাজির হয়েছিল?
এমপিটকাস

1

বেস সহ এটি করার আরও একটি উপায়:

dt<-data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,4,2))

data.frame(id=sort(unique(dt$var)),max=tapply(dt$var,dt$id,max))
  id max
1  1   4
2  2   3
3  3   4
4  4   2

যদিও আমি এমপিক্টাসের প্লাইয়ার সলিউশনটি পছন্দ করি।


1

উদাহরণস্বরূপ, কলামটি ইতিমধ্যে আরোহী ক্রমে থাকলে আমাদের ডেটা ফ্রেমকে সাজানোর দরকার নেই। আমরা কেবল duplicatedযুক্তিটি অতিক্রম করে ফাংশনটি ব্যবহার করি fromLast = TRUE, সুতরাং শেষ উপাদানগুলি রেখে উল্টো দিক থেকে সদৃশটি বিবেচনা করা হয়:

z <- data.frame(id=c(1,1,2,2,3,4),var=c(2,4,1,3,5,2))
z[!duplicated(z$id, fromLast = TRUE), ]

  id var
2  1   4
4  2   3
5  3   5
6  4   2

অন্যথায় আমরা ডেটা ফ্রেমটিকে প্রথমে আরোহণের ক্রমে বাছাই করি:

z <- z[order(z$id, z$var), ]
z[!duplicated(z$id, fromLast = TRUE), ]

dplyrপ্যাকেজ ব্যবহার :

library(dplyr)
z %>%
  group_by(id) %>%
  summarise(var = max(var))

Source: local data frame [4 x 2]    
  id var
1  1   4
2  2   3
3  3   5
4  4   2
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.