128

特定の変数にテキスト文字列が含まれているdata.frameがあります。個々の文字列での特定の文字の出現回数をカウントしたいと思います。

例:

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

文字列内の「a」の出現回数(つまり、c(2,1,0))を使用してq.dataの新しい列を作成したいと思います。

私が管理した唯一の複雑なアプローチは次のとおりです。

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
4

13 に答える 13

168

ストリンガーパッケージは、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
于 2012-09-14T15:25:40.847 に答える
76

ベースRを離れたくない場合は、かなり簡潔で表現力豊かな可能性があります。

x <- q.data$string
lengths(regmatches(x, gregexpr("a", x)))
# [1] 2 1 0
于 2012-09-14T15:44:03.463 に答える
21
nchar(as.character(q.data$string)) -nchar( gsub("a", "", q.data$string))
[1] 2 1 0

ncharに渡す前に、factor変数をcharacterに強制することに注意してください。正規表現関数はそれを内部的に行うように見えます。

ベンチマーク結果は次のとおりです(テストのサイズを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
于 2012-09-14T19:23:57.053 に答える
12

パッケージは、非常に高速stringiな機能stri_countを提供します。stri_count_fixed

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

基準

@ 42-の回答からの最速のアプローチ、および30.000要素のベクトルのパッケージからの同等の関数と比較。stringr

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),]

ここに画像の説明を入力してください

于 2019-03-07T20:27:05.907 に答える
10

charToRawを使用するもう1つの良いオプション:

sum(charToRaw("abc.d.aa") == charToRaw('.'))
于 2016-07-06T16:17:36.783 に答える
7

https://stackoverflow.com/a/12430764/589165のバリエーションは

> nchar(gsub("[^a]", "", q.data$string))
[1] 2 1 0
于 2019-08-09T18:11:47.673 に答える
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")
于 2012-09-14T15:23:59.490 に答える
1

文字列分割を使用できます

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

これにより、1、3、1、0が得られます。正規表現や単語全体で文字列除算を使用することもできます。

于 2018-10-03T16:15:07.830 に答える
0

IMHOが最も簡単でクリーンな方法は次のとおりです。

q.data$number.of.a <- lengths(gregexpr('a', q.data$string))

#  number     string number.of.a`
#1      1 greatgreat           2`
#2      2      magic           1`
#3      3        not           0`
于 2017-12-26T09:54:58.773 に答える
0

以下の質問はここに移動されましたが、このページはファラエルの質問に直接答えていないようです。 Rで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

于 2019-03-19T04:26:48.677 に答える
0

さらに別のbase Rオプションは次のとおりです。

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

[1] 2 1 0
于 2020-01-20T06:37:18.073 に答える
-1

次の式はその役割を果たし、文字だけでなく記号にも機能します。

式は次のように機能します。

1:データフレームq.dataの列でlapplyを使用して、列2の行を反復処理します( "lapply(q.data [、2]、")、

2:列2の各行に関数 "function(x){sum('a' == strsplit(as.character(x)、'')[[1]])}"を適用します。この関数は、列2(x)の各行の値を取得し、文字に変換し(たとえば、因子である場合)、すべての文字で文字列の分割を行います( "strsplit(as.character(x)、 ' ') ")。その結果、列2の各行の文字列値の各文字を含むベクトルが得られます。

3:ベクトルの各ベクトル値は、カウントする目的の文字(この場合は "a"( "'a' =="))と比較されます。この操作は、True値とFalse値のベクトル "c(True、False、True、....)"を返します。ベクトルの値が、カウントする目的の文字と一致すると、Trueになります。

4:文字「a」が行に表示される合計回数は、ベクトル「sum(....)」内のすべての「True」値の合計として計算されます。

5:次に、「unlist」関数を適用して、「lapply」関数の結果を解凍し、データフレーム内の新しい列に割り当てます( "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
于 2020-04-06T13:53:16.007 に答える
-2
s <- "aababacababaaathhhhhslsls jsjsjjsaa ghhaalll"
p <- "a"
s2 <- gsub(p,"",s)
numOcc <- nchar(s) - nchar(s2)

効率的なものではないかもしれませんが、私の目的を解決します。

于 2015-05-08T06:00:16.827 に答える