문자열 열의 각 행에서 주어진 문자의 발생 횟수를 계산하는 방법은 무엇입니까?
특정 변수에 텍스트 문자열이 포함된 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
stringr 패키지는 다음을 제공합니다.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
만약 당신이 기본 R을 떠나고 싶지 않다면, 여기 꽤 간결하고 표현적인 가능성이 있습니다:
x <- q.data$string
lengths(regmatches(x, gregexpr("a", x)))
# [1] 2 1 0
nchar(as.character(q.data$string)) -nchar( gsub("a", "", q.data$string))
[1] 2 1 0
nchar를 전달하기 전에 인자 변수를 문자로 강제 적용합니다.정규식 함수는 내부적으로 이를 수행하는 것으로 나타납니다.
다음은 벤치마크 결과입니다(테스트 크기를 3,000행으로 확대).
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
charToRaw를 사용하는 또 다른 좋은 옵션:
sum(charToRaw("abc.d.aa") == charToRaw('.'))
그stringi
패키지는 기능을 제공합니다.stri_count
그리고.stri_count_fixed
그것은 매우 빠릅니다.
stringi::stri_count(q.data$string, fixed = "a")
# [1] 2 1 0
기준이 되는
@42-의 답변에서 가장 빠른 접근 방식과 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),]
https://stackoverflow.com/a/12430764/589165 의 변형은 다음과 같습니다.
> nchar(gsub("[^a]", "", q.data$string))
[1] 2 1 0
누군가는 더 잘할 수 있지만, 이것은 효과가 있습니다.
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")
그냥 문자열 분할을 사용할 수 있습니다.
require(roperators)
my_strings <- c('apple', banana', 'pear', 'melon')
my_strings %s/% 'a'
그러면 1, 3, 1, 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
또 하나base R
옵션은 다음과 같습니다.
lengths(lapply(q.data$string, grepRaw, pattern = "a", all = TRUE, fixed = TRUE))
[1] 2 1 0
다음 식을 사용하면 문자뿐만 아니라 기호에도 사용할 수 있습니다.
식은 다음과 같이 작동합니다.
1: 데이터 프레임의 열에 lapply를 사용하여 q.data를 열 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: 그런 다음 "목록 해제" 기능을 적용하여 "적용" 기능의 결과를 압축 해제하고 데이터 프레임의 새 열에 할당합니다("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
@ @IRTFM을 사용하는 사람들)의보다 좋지 또 R stringi
/stringr
다른 :), 하만지다다낫습니다보들것른다.
sapply(strsplit(q.data$string, split=""), function(x) sum(x %in% "a"))
q.data<-data.frame(number=1:3, string=c("greatgreat", "magic", "not"))
q.data<-q.data[rep(1:NROW(q.data), 3000),]
library(rbenchmark)
library(stringr)
library(stringi)
benchmark( Dason = {str_count(q.data$string, "a") },
Tim = {sapply(q.data$string, function(x, letter = "a"){sum(unlist(strsplit(x, split = "")) == letter) }) },
DWin = {nchar(q.data$string) -nchar( gsub("a", "", q.data$string, fixed=TRUE))},
Markus = {stringi::stri_count(q.data$string, fixed = "a")},
Finn={nchar(gsub("[^a]", "", q.data$string))},
tmmfmnk={lengths(lapply(q.data$string, grepRaw, pattern = "a", all = TRUE, fixed = TRUE))},
Josh1 = {sapply(regmatches(q.data$string, gregexpr("g",q.data$string )), length)},
Josh2 = {lengths(regmatches(q.data$string, gregexpr("g",q.data$string )))},
Iago = {sapply(strsplit(q.data$string, split=""), function(x) sum(x %in% "a"))},
replications =100, order = "elapsed")
test replications elapsed relative user.self sys.self user.child sys.child
4 Markus 100 0.076 1.000 0.076 0.000 0 0
3 DWin 100 0.277 3.645 0.277 0.000 0 0
1 Dason 100 0.290 3.816 0.291 0.000 0 0
5 Finn 100 1.057 13.908 1.057 0.000 0 0
9 Iago 100 3.214 42.289 3.215 0.000 0 0
2 Tim 100 6.000 78.947 6.002 0.000 0 0
6 tmmfmnk 100 6.345 83.487 5.760 0.003 0 0
8 Josh2 100 12.542 165.026 12.545 0.000 0 0
7 Josh1 100 13.288 174.842 13.268 0.028 0 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`
s <- "aababacababaaathhhhhslsls jsjsjjsaa ghhaalll"
p <- "a"
s2 <- gsub(p,"",s)
numOcc <- nchar(s) - nchar(s2)
효율적이지는 않지만 내 목적을 해결할 수 있습니다.
언급URL : https://stackoverflow.com/questions/12427385/how-to-calculate-the-number-of-occurrence-of-a-given-character-in-each-row-of-a
'programing' 카테고리의 다른 글
Git 이등분 오류 실행 취소 (0) | 2023.06.30 |
---|---|
PyTorch 모형의 총 모수 수 확인 (0) | 2023.06.30 |
Firebase 프로젝트에서 앱을 삭제/제거하려면 어떻게 해야 합니까? (0) | 2023.06.30 |
Oracle 패키지 수준 변수의 범위 (0) | 2023.06.30 |
Ruby의 base64 인코딩 문자열에 이상한 \n (0) | 2023.06.30 |