একাধিক নিদর্শন সহ একটি অক্ষর ভেক্টর ব্যবহার করে গ্রেপ করুন


132

আমি grepস্ট্রিংগুলির একটি ভেক্টর অন্য ভেক্টরটিতে উপস্থিত কিনা তা পরীক্ষা করার জন্য এবং উপস্থিত মানগুলিকে আউটপুট করতে (মিলনীয় নিদর্শনগুলি) পরীক্ষা করার চেষ্টা করছি।

আমার কাছে এই জাতীয় ডেটা ফ্রেম রয়েছে:

FirstName Letter   
Alex      A1
Alex      A6
Alex      A7
Bob       A1
Chris     A9
Chris     A6

আমি স্ট্রিং রীতির একটি ভেক্টর, "চিঠি" কলাম পাওয়া যাবে উদাহরণস্বরূপ আছে: c("A1", "A9", "A6")

আমি পরীক্ষা করতে চাই যে প্যাটার্ন ভেক্টরের যে কোনও স্ট্রিং "লেটার" কলামে উপস্থিত কিনা। যদি সেগুলি হয় তবে আমি অনন্য মানগুলির আউটপুট চাই।

সমস্যাটি হচ্ছে, আমি grepএকাধিক নিদর্শন দিয়ে কীভাবে ব্যবহার করব তা জানি না । আমি চেষ্টা করেছিলাম:

matches <- unique (
    grep("A1| A9 | A6", myfile$Letter, value=TRUE, fixed=TRUE)
)

তবে এটি আমাকে ০ টি ম্যাচ দেয় যা সত্য নয়, কোনও পরামর্শ?


3
আপনি ব্যবহার করতে পারবেন না fixed=TRUEকারণ আপনি প্যাটার্ন হয় সত্য রেগুলার এক্সপ্রেশন।
মারেক 15

6
সঠিক মিলগুলি তুলনা করার একমাত্র সঠিক উপায় ব্যবহার matchবা %in%বা এমনকি ==হ'ল । রিজেেক্স এই জাতীয় কাজের জন্য খুব বিপজ্জনক এবং অপ্রত্যাশিত ফলাফলের দিকে নিয়ে যেতে পারে।
ডেভিড আরেনবার্গ

উত্তর:


269

অন্তর্ভুক্ত না করার বিষয়ে @ মারেকের মন্তব্য ছাড়াও fixed==TRUE, আপনার নিয়মিত প্রকাশের ক্ষেত্রে আপনার ফাঁকা স্থানও থাকা উচিত নয়। এটা হওয়া উচিত "A1|A9|A6"

আপনি আরও উল্লেখ করেন যে প্রচুর নিদর্শন রয়েছে। ধরে নিচ্ছি যে তারা কোনও ভেক্টরে রয়েছে

toMatch <- c("A1", "A9", "A6")

তারপরে আপনি সরাসরি pasteএবং ব্যবহার করে আপনার নিয়মিত প্রকাশ তৈরি করতে পারেন collapse = "|"

matches <- unique (grep(paste(toMatch,collapse="|"), 
                        myfile$Letter, value=TRUE))

আপনার স্ট্রিংগুলির তালিকায় রেগেক্স অপারেটরগুলিকে বিরামচিহ্ন হিসাবে অন্তর্ভুক্ত করার সময় এটি করার কোনও উপায়?
ব্যবহারকারী 124123

@ ব্যবহারকারী1987097 এটি অন্যভাবে কোনও রেইগেক্স অপারেটরদের সাথে বা ছাড়াই একইভাবে কাজ করা উচিত। আপনার কোন নির্দিষ্ট উদাহরণ রয়েছে যা এর জন্য কার্যকর হয়নি?
ব্রায়ান ডিগস

@ ব্যবহারকারী1987097 কোনও বিন্দু বা বন্ধনী দেওয়ার আগে 2 টি ব্যাকস্ল্যাশ ব্যবহার করুন। প্রথম ব্যাকস্ল্যাশ অপারেটরকে অক্ষম করার জন্য প্রয়োজনীয় দ্বিতীয়টির ব্যাখ্যা করার জন্য একটি পালানোর চরিত্র।
mbh86

3
সঠিক ম্যাচের জন্য রেজেক্স ব্যবহার করা আমার পক্ষে বিপজ্জনক বলে মনে হচ্ছে এবং অপ্রত্যাশিত ফলাফল হতে পারে। শুধু কেন নয় toMatch %in% myfile$Letter?
ডেভিড আরেনবুর্গ

@ ব্যবহারকারী 4050 কোনও নির্দিষ্ট কারণ নেই। প্রশ্নের সংস্করণটিতে এটি ছিল এবং আমি সম্ভবত এটি প্রয়োজনীয় কিনা তা ভেবেই কেবল এটি চালিয়েছি।
ব্রায়ান ডিগস

34

ভাল উত্তর, তবে filter()dplyr থেকে ভুলবেন না :

patterns <- c("A1", "A9", "A6")
>your_df
  FirstName Letter
1      Alex     A1
2      Alex     A6
3      Alex     A7
4       Bob     A1
5     Chris     A9
6     Chris     A6

result <- filter(your_df, grepl(paste(patterns, collapse="|"), Letter))

>result
  FirstName Letter
1      Alex     A1
2      Alex     A6
3       Bob     A1
4     Chris     A9
5     Chris     A6

3
আমি মনে করি যে greplসেই সময়ে একটি প্যাটার্নের সাথে কাজ করে (আমাদের দৈর্ঘ্য 1 সহ ভেক্টর প্রয়োজন), আমাদের 3 টি প্যাটার্ন রয়েছে (3 দৈর্ঘ্যের ভেক্টর), তাই আমরা গ্রেপল বিভাজকের জন্য কিছু বন্ধুত্বপূর্ণ ব্যবহার করে তাদের সাথে একত্রিত করতে পারি - |, অন্যটির সাথে আপনার ভাগ্য চেষ্টা করুন :)
আদম

3
ওহ আমি এখন এটি পেতে। সুতরাং এটি A1 এর মতো আউটপুট করার একটি সংকোচনের উপায় এ 2 সুতরাং যদি কেউ সমস্ত শর্ত চায় তবে পতনটি একটি চিহ্ন & চিহ্ন সহ হবে, শীতল ধন্যবাদ।
আহাদে

1
হাই, ব্যবহার )|(পৃথক নিদর্শন এই আরো জোরালো করা হতে পারে: paste0("(", paste(patterns, collapse=")|("),")")। দুর্ভাগ্যক্রমে এটি কিছুটা কম ইজেন্টেন্টও হয়ে যায়। এটি প্যাটার্নে ফলাফল (A1)|(A9)|(A6)
ফেবার্ন

14

এই কাজ করা উচিত:

grep(pattern = 'A1|A9|A6', x = myfile$Letter)

বা আরও সহজভাবে:

library(data.table)
myfile$Letter %like% 'A1|A9|A6'

11
%like%বেস আর তে নেই, সুতরাং এটি ব্যবহার করার জন্য কোন প্যাকেজ (গুলি) দরকার তা আপনার উল্লেখ করা উচিত।
গ্রেগর থমাস

1
অন্যদের জন্য এই উত্তরটি খুঁজছেন, প্যাকেজের %like%অংশ data.table। এছাড়াও অনুরূপ data.tableহয় like(...), %ilike%এবং %flike%
স্টিভ

8

ব্রায়ান ডিগের পোস্টের ভিত্তিতে, ফিল্টারিং তালিকার জন্য এখানে দুটি কার্যকারী কার্যকারিতা রয়েছে:

#Returns all items in a list that are not contained in toMatch
#toMatch can be a single item or a list of items
exclude <- function (theList, toMatch){
  return(setdiff(theList,include(theList,toMatch)))
}

#Returns all items in a list that ARE contained in toMatch
#toMatch can be a single item or a list of items
include <- function (theList, toMatch){
  matches <- unique (grep(paste(toMatch,collapse="|"), 
                          theList, value=TRUE))
  return(matches)
}

5

আপনি চেষ্টা করেছেন match()বা charmatch()কাজগুলি?

উদাহরণ ব্যবহার:

match(c("A1", "A9", "A6"), myfile$Letter)

1
একটি বিষয় লক্ষণীয় matchযে এটি নিদর্শনগুলি ব্যবহার করছে না, এটি সঠিক মিলের প্রত্যাশা করছে।
স্টিভ

5

এই উত্তরটি ইতিমধ্যে উপস্থিত হয়েছে কিনা তা নিশ্চিত নয় ...

প্রশ্নের নির্দিষ্ট প্যাটার্নের জন্য, আপনি কেবল এটি একটি grep()কল দিয়ে করতে পারেন ,

grep("A[169]", myfile$Letter)

4

ব্রায়ান ডিগস উত্তর যুক্ত করতে।

গ্রেপল ব্যবহার করার অন্য একটি উপায় আপনার সমস্ত মান সমেত একটি ডেটা ফ্রেম ফিরিয়ে দেবে।

toMatch <- myfile$Letter

matches <- myfile[grepl(paste(toMatch, collapse="|"), myfile$Letter), ]

matches

Letter Firstname
1     A1      Alex 
2     A6      Alex 
4     A1       Bob 
5     A9     Chris 
6     A6     Chris

কিছুটা ক্লিনার হতে পারে ... হয়তো?


2

স্থানগুলি সরিয়ে নিন। তাই:

matches <- unique(grep("A1|A9|A6", myfile$Letter, value=TRUE, fixed=TRUE))

1

ব্যবহার করে sapply

 patterns <- c("A1", "A9", "A6")
         df <- data.frame(name=c("A","Ale","Al","lex","x"),Letters=c("A1","A2","A9","A1","A9"))



   name Letters
1    A      A1
2  Ale      A2
3   Al      A9
4  lex      A1
5    x      A9


 df[unlist(sapply(patterns, grep, df$Letters, USE.NAMES = F)), ]
  name Letters
1    A      A1
4  lex      A1
3   Al      A9
5    x      A9

-1

আমি একটু স্ক্রিপ্ট লেখার এবং গ্রেপের সাথে একাধিক অনুসন্ধান করার পরামর্শ দিচ্ছি। আমি একাধিক নিদর্শন অনুসন্ধান করার উপায় খুঁজে পাই নি, এবং বিশ্বাস করুন, আমি দেখেছি!

এম্বেড স্ট্রিং সহ আপনার শেল ফাইলটি এর মতো:

 #!/bin/bash 
 grep *A6* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A7* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";
 grep *A8* "Alex A1 Alex A6 Alex A7 Bob A1 Chris A9 Chris A6";

তারপরে myshell.sh টাইপ করে চালান।

আপনি যদি কমান্ড লাইনের স্ট্রিংটিতে পাস করতে সক্ষম হতে চান তবে শেল আর্গুমেন্টের সাহায্যে এটি করুন - এটি হ'ল বাশ চিহ্নিতকরণ বিটিডব্লিউ:

 #!/bin/bash 
 $stingtomatch = "${1}";
 grep *A6* "${stingtomatch}";
 grep *A7* "${stingtomatch}";
 grep *A8* "${stingtomatch}";

এবং তাই এগিয়ে।

যদি মেলানোর মতো অনেকগুলি নিদর্শন থাকে তবে আপনি এটি লুপের জন্য রাখতে পারেন।


ধন্যবাদ ক্রিসবিয়ান নিদর্শনগুলি আসলে প্রচুর এবং সম্ভবত কোনও ফাইল ব্যবহার করা ভাল। আমি বেসে নতুন, তবে সম্ভবত এই জাতীয় কিছু কাজ করা উচিত ... #! যদি [$ j -eq o] তবে প্রতিধ্বনি করুন $ i >>
ম্যাচস.টেক্সট

কাজ করে না ... ত্রুটি বার্তাটি '[গ্রেপ: কমান্ড পাওয়া যায় নি' ... আমার কাছে / বিন ফোল্ডারে গ্রিপ রয়েছে, এবং / বিন আমার $ রাস্তায় আছে ... নিশ্চিত যে নিশ্চিত হচ্ছে না ... আপনি দয়া করে সহায়তা করতে পারেন?
ব্যবহারকারী 971102
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.