স্ট্রিংগুলির একটি কলামের প্রতিটি সারিতে প্রদত্ত চরিত্রের সংখ্যার গণনা কীভাবে করবেন?


103

আমার একটি ডেটা ফ্রেম রয়েছে যাতে নির্দিষ্ট ভেরিয়েবলের একটি পাঠ্য স্ট্রিং থাকে। আমি প্রতিটি স্বতন্ত্র স্ট্রিংয়ে প্রদত্ত একটি চরিত্রের সংখ্যার সংখ্যা গণনা করতে চাই।

উদাহরণ:

q.data<-data.frame(number=1:3, string=c("greatgreat", "magic", "not"))

আমি q.data এর জন্য স্ট্রিংয়ের "a" এর সংখ্যার সংখ্যা (যেমন সি (২,১,০)) সহ একটি নতুন কলাম তৈরি করতে চাই।

আমি পরিচালিত একমাত্র বিশৃঙ্খলা পদ্ধতি:

string.counter<-function(strings, pattern){  
  counts<-NULL
  for(i in 1:length(strings)){
    counts[i]<-length(attr(gregexpr(pattern,strings[i])[[1]], "match.length")[attr(gregexpr(pattern,strings[i])[[1]], "match.length")>0])
  }
return(counts)
}

string.counter(strings=q.data$string, pattern="a")

 number     string number.of.a
1      1 greatgreat           2
2      2      magic           1
3      3        not           0

উত্তর:


141

স্ট্রিংগার প্যাকেজটি এমন str_countফাংশন সরবরাহ করে যা মনে হয় আপনি যা আগ্রহী তা করেন

# Load your example data
q.data<-data.frame(number=1:3, string=c("greatgreat", "magic", "not"), stringsAsFactors = F)
library(stringr)

# Count the number of 'a's in each element of string
q.data$number.of.a <- str_count(q.data$string, "a")
q.data
#  number     string number.of.a
#1      1 greatgreat           2
#2      2      magic           1
#3      3        not           0

1
আপনারটি খুব দ্রুত ছিল যদিও মূলত যুক্তিটির আশেপাশে সমস্যাটির সাথে সাফল্যের জন্য একটি as.character () দরকার নেই।
আইআরটিএফএম

1
@ ডুইন - এটি সত্য তবে stringsAsFactors = FALSEডেটা ফ্রেম সংজ্ঞায়িত করার সময় আমি এ সমস্যাটি এড়াতে পেরেছি ।
Dason

দুঃখিত আমি অস্পষ্ট ছিলাম। আমি আসলে টিম রিফকে প্রতিক্রিয়া জানিয়েছিলাম এবং তাকে বলছিলাম যে তার ফাংশনটি সমস্যার সম্মুখীন হওয়ার সাথে একটি ত্রুটি ফেলেছে। তিনি আপনার সমস্যার নতুন সংজ্ঞা ব্যবহার করতে পারেন তবে তিনি তা বলেননি।
আইআরটিএফএম

হ্যাঁ, আমি stringsAsFactors=TRUEআমার কম্পিউটারেও করেছি, তবে এটি উল্লেখ করিনি
টিম রিফ

কোনও ফ্যাক্টরের স্ট্রিং অনুসন্ধান করা কাজ করবে যেমন str_count (d $ factor_column, 'A') তবে বিপরীত নয়
নাইট্রো

65

আপনি যদি বেস আর ছাড়তে না চান তবে এখানে মোটামুটি সংক্ষিপ্ত এবং অভিব্যক্তিপূর্ণ সম্ভাবনা রয়েছে:

x <- q.data$string
lengths(regmatches(x, gregexpr("a", x)))
# [1] 2 1 0

2
ঠিক আছে - সম্ভবত আপনি একবারে এবং কয়েকবার একসাথে একবার ব্যবহার করার পরে তা কেবলমাত্র ভাবের অনুভূতি বোধ করবে তবে সেই কম্বোটি যথেষ্ট শক্তিশালী যে আমি ভেবেছিলাম এটি একটি প্লাগের জন্য প্রাপ্য। regmatchesgregexpr
জোশ ওব্রায়েন

regmatchesতুলনামূলকভাবে নতুন। এটি 2.14 সালে চালু হয়েছিল।
Dason

আমার মনে হয় না আপনার রেজিমেচ কিছুটা দরকার। ফাংশন গ্রেজেক্সপ্রে x এর প্রতিটি উপাদানের সাথে মিলে যাওয়া ঘটনার সূচকগুলির সাথে একটি তালিকা প্রদান করে।
ক্ষয়ক্ষতি

@ সাভেজেন্ট - আপনি প্রতিটি স্ট্রিংয়ে ম্যাচের সংখ্যা গণনা করতে যে কোডটি ব্যবহার করবেন তা ভাগ করে নিতে আপনি কি আপত্তি করবেন?
জোশ

1
দুঃখিত, আমি -1 সম্পর্কে ভুলে গেছি এটি কেবলমাত্র যদি প্রতিটি লাইনে কমপক্ষে একটি ম্যাচ থাকে তবে সেপ্লাই করে (গ্রেজেক্সারপ্রি ("g", q.data $ স্ট্রিং), দৈর্ঘ্য) থাকে works
ক্ষিপ্ত

17
nchar(as.character(q.data$string)) -nchar( gsub("a", "", q.data$string))
[1] 2 1 0

লক্ষ্য করুন যে আমি এনসিআর-এ যাওয়ার আগে ফ্যাক্টর ভেরিয়েবলকে অক্ষর করতে বাধ্য করি। রেজেক্স ফাংশনগুলি অভ্যন্তরীণভাবে এটি করতে দেখা যায়।

এখানে মাপদণ্ডের ফলাফল (পরীক্ষার আকার বাড়িয়ে রাখা আকারের সাথে 3000 সারি)

 q.data<-q.data[rep(1:NROW(q.data), 1000),]
 str(q.data)
'data.frame':   3000 obs. of  3 variables:
 $ number     : int  1 2 3 1 2 3 1 2 3 1 ...
 $ string     : Factor w/ 3 levels "greatgreat","magic",..: 1 2 3 1 2 3 1 2 3 1 ...
 $ number.of.a: int  2 1 0 2 1 0 2 1 0 2 ...

 benchmark( Dason = { q.data$number.of.a <- str_count(as.character(q.data$string), "a") },
 Tim = {resT <- sapply(as.character(q.data$string), function(x, letter = "a"){
                            sum(unlist(strsplit(x, split = "")) == letter) }) }, 

 DWin = {resW <- nchar(as.character(q.data$string)) -nchar( gsub("a", "", q.data$string))},
 Josh = {x <- sapply(regmatches(q.data$string, gregexpr("g",q.data$string )), length)}, replications=100)
#-----------------------
   test replications elapsed  relative user.self sys.self user.child sys.child
1 Dason          100   4.173  9.959427     2.985    1.204          0         0
3  DWin          100   0.419  1.000000     0.417    0.003          0         0
4  Josh          100  18.635 44.474940    17.883    0.827          0         0
2   Tim          100   3.705  8.842482     3.646    0.072          0         0

2
এটি উত্তরের দ্রুততম সমাধান তবে benchচ্ছিকটি পাস করে আপনার বেঞ্চমার্কে ~ 30% দ্রুত তৈরি করা fixed=TRUEহয় gsub। এছাড়া মামলা কোথায় আছেন তা fixed=TRUEহবে প্রয়োজনীয় (অর্থাত, যখন অক্ষর আপনি গণনা করতে চান এর মত Regex কথন হিসেবে ব্যাখ্যা করা যেতে পারে .)।
C8H10N4O2


5

stringiপ্যাকেজ ফাংশন প্রদান করে stri_countএবং stri_count_fixedযা খুবই দ্রুত।

stringi::stri_count(q.data$string, fixed = "a")
# [1] 2 1 0

মাপকাঠি

থেকে দ্রুততম পদ্ধতির তুলনায় @ 42-এর উত্তর এবং থেকে সমতুল্য ফাংশন stringrপ্যাকেজ 30.000 উপাদানের সঙ্গে একটি ভেক্টর জন্য।

library(microbenchmark)

benchmark <- microbenchmark(
  stringi = stringi::stri_count(test.data$string, fixed = "a"),
  baseR = nchar(test.data$string) - nchar(gsub("a", "", test.data$string, fixed = TRUE)),
  stringr = str_count(test.data$string, "a")
)

autoplot(benchmark)

উপাত্ত

q.data <- data.frame(number=1:3, string=c("greatgreat", "magic", "not"), stringsAsFactors = FALSE)
test.data <- q.data[rep(1:NROW(q.data), 10000),]

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



2

আমি নিশ্চিত কেউ আরও ভাল করতে পারে তবে এটি কাজ করে:

sapply(as.character(q.data$string), function(x, letter = "a"){
  sum(unlist(strsplit(x, split = "")) == letter)
})
greatgreat      magic        not 
     2          1          0 

বা একটি ফাংশনে:

countLetter <- function(charvec, letter){
  sapply(charvec, function(x, letter){
    sum(unlist(strsplit(x, split = "")) == letter)
  }, letter = letter)
}
countLetter(as.character(q.data$string),"a")

আমি প্রথমটির সাথে একটি ত্রুটি পেয়েছি বলে মনে হচ্ছে ... এবং দ্বিতীয়টি ... (এই
সমস্তটি বেনমার্ক

1

আপনি কেবল স্ট্রিং বিভাগ ব্যবহার করতে পারেন

require(roperators)
my_strings <- c('apple', banana', 'pear', 'melon')
my_strings %s/% 'a'

যা আপনাকে 1, 3, 1, 0 দেবে regular আপনি নিয়মিত প্রকাশ এবং পুরো শব্দ সহ স্ট্রিং বিভাগও ব্যবহার করতে পারেন।



0

নীচের প্রশ্নটি এখানে সরানো হয়েছে, তবে মনে হয় এই পৃষ্ঠাটি ফারাহ এল এর প্রশ্নের সরাসরি উত্তর দেয় না। আর-তে 101 তে 1 নম্বর কীভাবে পাবেন

সুতরাং, আমি এখানে একটি উত্তর লিখব, কেবল ক্ষেত্রে।

library(magrittr)
n %>% # n is a number you'd like to inspect
  as.character() %>%
  str_count(pattern = "1")

https://stackoverflow.com/users/8931457/farah-el


0

তবুও অন্য base Rবিকল্প হতে পারে:

lengths(lapply(q.data$string, grepRaw, pattern = "a", all = TRUE, fixed = TRUE))

[1] 2 1 0

-1

পরবর্তী প্রকাশটি কাজ করে এবং চিহ্নগুলির জন্যও কাজ করে, কেবল অক্ষর নয় letters

এক্সপ্রেশন নিম্নলিখিত হিসাবে কাজ করে:

1: এটি ডেটাফ্রেম q.data এর কলামগুলিতে ল্যাপলি ব্যবহার করে কলাম 2 ("ল্যাপলি (q.data [, 2],") এর সারিগুলিতে পুনরাবৃত্তি করতে,

2: এটি কলামের প্রতিটি সারিটিতে একটি ফাংশন "ফাংশন (x) {যোগ ('a' == স্টারস্প্লিট (as.character (x), '') [[1]])}" প্রযোজ্য। "।" ফাংশনটি কলাম 2 (x) এর প্রতিটি সারি মান গ্রহণ করে, চরিত্রে রূপান্তর করে (যদি এটি উদাহরণস্বরূপ একটি ফ্যাক্টর হয়) এবং এটি প্রতিটি অক্ষরে স্ট্রিংয়ের বিভাজন করে ("স্টারস্প্লিট (as.character (x), ' ') ")। ফলস্বরূপ আমাদের কলাম 2 এর প্রতিটি সারিটির স্ট্রিং মানের প্রতিটি অক্ষর সহ আ ভেক্টর রয়েছে।

3: ভেক্টরের প্রতিটি ভেক্টর মান গণনা করার জন্য পছন্দসই অক্ষরটির সাথে তুলনা করা হয়, এই ক্ষেত্রে "এ" ("'এ' ==")। এই অপারেশনটি সত্য এবং মিথ্যা মানগুলির একটি ভেক্টরকে "সি (সত্য, মিথ্যা, সত্য, ....)" ফিরিয়ে দেবে, যখন ভেক্টরের মান গণনা করা পছন্দসই অক্ষরের সাথে মেলে।

4: সারিতে প্রদর্শিত 'ক' অক্ষরটি মোট ভেক্টর "যোগ (....)" এর সমস্ত 'সত্য' মানের যোগফল হিসাবে গণনা করা হয়।

5: তারপরে "ল্যাপলি" ফাংশনটির ফলাফল আনপ্যাক করার জন্য এটি "আনলিস্ট" ফাংশন প্রয়োগ করা হয় এবং এটি ডেটাফ্রেমে নতুন কলামে বরাদ্দ করা হয় ("q.data $ number.of.a <-unlist (.... ")

q.data$number.of.a<-unlist(lapply(q.data[,2],function(x){sum('a' == strsplit(as.character(x), '')[[1]])}))

>q.data

#  number     string     number.of.a
#1   greatgreat         2
#2      magic           1
#3      not             0

1
আপনার উত্তরটি এটি যা করে তার একটি ব্যাখ্যার সাথে আরও ভাল হতে পারে, বিশেষত নতুন ব্যবহারকারীদের জন্য এটি ঠিক সাধারণ অভিব্যক্তি নয়।
খাইন 775

আপনার মন্তব্যের জন্য @ খাইন the75৫ ধন্যবাদ এবং পোস্টটির বর্ণনার অভাবের জন্য দুঃখিত। আমি পোস্টটি সম্পাদনা করেছি এবং এটি কীভাবে কাজ করে তার আরও ভাল বিবরণের জন্য কিছু মন্তব্য যুক্ত করেছি।
বেকনকন

-2
s <- "aababacababaaathhhhhslsls jsjsjjsaa ghhaalll"
p <- "a"
s2 <- gsub(p,"",s)
numOcc <- nchar(s) - nchar(s2)

দক্ষ না হতে পারে তবে আমার উদ্দেশ্য সমাধান করুন।

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