Bir dizedeki kelimelerin sayısını sayan bir işlev var mı? Örneğin:
str1 <- "How many words are in this sentence"
7 sonucu döndürmek için.
Bir dizedeki kelimelerin sayısını sayan bir işlev var mı? Örneğin:
str1 <- "How many words are in this sentence"
7 sonucu döndürmek için.
Yanıtlar:
strsplit
Ve sapply
işlevlerini kullanabilirsiniz
sapply(strsplit(str1, " "), length)
lengths
Her bir elementin uzunluğunu bulan, artık R tabanındaki biraz yeni fonksiyonu kullanabileceğiniz bir güncelleme :lengths(strsplot(str, " "))
\\W
Sözcük olmayan karakterleri eşleştirmek için normal ifade sembolünü +
, bir satırdaki bir veya daha fazlasını belirtmek için kullanarak gregexpr
ve bir dizedeki tüm eşleşmeleri bulmak için kullanın. Kelimeler, kelime ayırıcılarının sayısı artı 1'dir.
lengths(gregexpr("\\W+", str1)) + 1
Bir "kelime" tatmin etmiyor, bu başına veya karakter vektörü, sonunda boş dizeleri başarısız olur \\W
s' olmayan kelimenin kavramını (bir Normal ifadelerle, birlikte işe yarayabilir \\S+
, [[:alpha:]]
vb, ama orada her zaman olacak normal ifade yaklaşımı olan uç durumlar olabilir), vb. Muhtemelen strsplit
her kelime için bellek ayıran çözümlerden daha etkilidir . Normal ifadeler bölümünde açıklanmıştır ?regex
.
Güncelleme Yorumlarda ve @Andri tarafından farklı bir yanıtta belirtildiği gibi, yaklaşım (sıfır) ve tek kelimelik dizelerle ve sonunda noktalama işaretiyle başarısız oluyor
str1 = c("", "x", "x y", "x y!" , "x y! z")
lengths(gregexpr("[A-z]\\W+", str1)) + 1L
# [1] 2 2 2 3 3
Diğer yanıtların çoğu da bu veya benzer (örneğin, birden çok boşluk) durumlarda başarısız olur. Bence cevabımın orijinal cevaptaki 'tek kelime kavramı' konusundaki uyarısı noktalama işaretleriyle ilgili sorunları kapsıyor (çözüm: farklı bir normal ifade seçin, örneğin, [[:space:]]+
), ancak sıfır ve tek kelimelik durumlar bir problem; @ Andri'nin çözümü sıfır ve bir kelimeyi ayırt edemiyor. Bu nedenle, birinin yapabileceği kelimeleri bulmak için 'olumlu'
sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
Giden
sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
# [1] 0 1 2 2 3
Yine normal ifade, farklı 'kelime' kavramları için iyileştirilebilir.
gregexpr()
Hafıza verimli olduğu için kullanımını seviyorum . Kullanan strsplit()
(@ user813966 gibi, ancak sözcükleri sınırlandırmak için normal bir ifadeyle) ve orijinal sınırlayıcı sözcük kavramını kullanan alternatif bir
lengths(strsplit(str1, "\\W+"))
# [1] 0 1 2 2 3
Bunun, oluşturulan her kelime için ve ara kelime listesi için yeni hafıza ayırması gerekir. Veriler 'büyük' olduğunda bu nispeten pahalı olabilir, ancak muhtemelen çoğu amaç için etkili ve anlaşılabilirdir.
str1 <- c('s ss sss ss', "asdf asd hello this is your life!"); sapply(gregexpr("\\W+", str1), length) + 1
döner 4
ve 8
. Birincisi doğru, ikincisi çok fazla. Sanırım noktalama işaretlerini sayıyor.
sapply(gregexpr("\\W+", "word"), length) + 1
2 döndürür
En basit yol şudur:
require(stringr)
str_count("one, two three 4,,,, 5 6", "\\S+")
... boşluksuz karakterler üzerindeki tüm dizileri sayar ( \\S+
).
Peki ya hangi tür kelimeleri saymak istediğimize ve hangisinin tüm vektörler üzerinde çalıştığına karar vermemizi sağlayan küçük bir fonksiyona ne dersiniz ?
require(stringr)
nwords <- function(string, pseudo=F){
ifelse( pseudo,
pattern <- "\\S+",
pattern <- "[[:alpha:]]+"
)
str_count(string, pattern)
}
nwords("one, two three 4,,,, 5 6")
# 3
nwords("one, two three 4,,,, 5 6", pseudo=T)
# 6
Kullanmak str_count
işlevini stringr
çıkış sırası ile kütüphane \w
temsil eder:
herhangi bir 'kelime' karakteri (mevcut yerel ayarda harf, rakam veya alt çizgi: UTF-8 modunda yalnızca ASCII harfleri ve rakamları dikkate alınır)
Misal:
> str_count("How many words are in this sentence", '\\w+')
[1] 7
Test edebildiğim tüm diğer 9 cevaptan sadece ikisi (Vincent Zoonekynd ve petermeissner tarafından) şimdiye kadar burada sunulan tüm girdiler için çalıştı, ancak bunlar da gerekli stringr
.
Ancak yalnızca bu çözüm, şimdiye kadar sunulan tüm girdiler artı "foo+bar+baz~spam+eggs"
veya gibi girdilerle çalışır "Combien de mots sont dans cette phrase ?"
.
Kıyaslama:
library(stringr)
questions <-
c(
"", "x", "x y", "x y!", "x y! z",
"foo+bar+baz~spam+eggs",
"one, two three 4,,,, 5 6",
"How many words are in this sentence",
"How many words are in this sentence",
"Combien de mots sont dans cette phrase ?",
"
Day after day, day after day,
We stuck, nor breath nor motion;
"
)
answers <- c(0, 1, 2, 2, 3, 5, 6, 7, 7, 7, 12)
score <- function(f) sum(unlist(lapply(questions, f)) == answers)
funs <-
c(
function(s) sapply(gregexpr("\\W+", s), length) + 1,
function(s) sapply(gregexpr("[[:alpha:]]+", s), function(x) sum(x > 0)),
function(s) vapply(strsplit(s, "\\W+"), length, integer(1)),
function(s) length(strsplit(gsub(' {2,}', ' ', s), ' ')[[1]]),
function(s) length(str_match_all(s, "\\S+")[[1]]),
function(s) str_count(s, "\\S+"),
function(s) sapply(gregexpr("\\W+", s), function(x) sum(x > 0)) + 1,
function(s) length(unlist(strsplit(s," "))),
function(s) sapply(strsplit(s, " "), length),
function(s) str_count(s, '\\w+')
)
unlist(lapply(funs, score))
Çıktı:
6 10 10 8 9 9 7 6 6 11
'[\\w\']+'
(test edemezsiniz , bu nedenle xkcd.com/1638 geçerli olabilir), aksi takdirde emin değilim regex, genel durumda başa
'\\w+(\'\\w{1,2})?'
iyi bir çözüm olabilir.
o'clock
ve friggin'
yapabilirsin \w+('\w*)?
(Kesme işaretiyle başlayan kelimeler var mı bilmiyorum?). Ek olarak saatleri idare etmek için, onları benzer şekilde eşleştirmeye çalışabilir \d?\d:\d\d|\w+('\w*)?
veya ihtiyaçlarınıza bağlı olarak daha da karmaşık bir şey yapabilirsiniz. Ancak bu, R ile ilgili gittikçe daha az ve bir kelimeyi nasıl tanımladığınızla ilgili, bu yüzden belki özel ihtiyaçlarınızı karşılamak için ayrı bir soru gönderebilirsiniz?
str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])
gsub(' {2,}',' ',str1)
Yapar Tüm kelimeleri bir boşluk olan iki ya da daha fazla boşluk her tekrarlarını değiştirerek, sadece bir boşluk ile ayrılır.
strsplit(str,' ')
Her boşluktaki cümleyi böler ve bir liste halinde sonuç döndürür. Bu [[1]]
listeden kelimelerin vektörünü alır. length
Kaç kelimeleri sayar.
> str1 <- "How many words are in this sentence"
> str2 <- gsub(' {2,}',' ',str1)
> str2
[1] "How many words are in this sentence"
> strsplit(str2,' ')
[[1]]
[1] "How" "many" "words" "are" "in" "this" "sentence"
> strsplit(str2,' ')[[1]]
[1] "How" "many" "words" "are" "in" "this" "sentence"
> length(strsplit(str2,' ')[[1]])
[1] 7
str_match_all
Kelimelerinizi tanımlayacak normal bir ifade ile kullanabilirsiniz . Aşağıdakiler ilk, son ve çoğaltılmış boşluklarla çalışır.
library(stringr)
s <- "
Day after day, day after day,
We stuck, nor breath nor motion;
"
m <- str_match_all( s, "\\S+" ) # Sequences of non-spaces
length(m[[1]])
Bu işlevi stringi
paketten deneyin
require(stringi)
> s <- c("Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
+ "nibh augue, suscipit a, scelerisque sed, lacinia in, mi.",
+ "Cras vel lorem. Etiam pellentesque aliquet tellus.",
+ "")
> stri_stats_latex(s)
CharsWord CharsCmdEnvir CharsWhite Words Cmds Envirs
133 0 30 24 0 0
" "
Sözcük sayısını elde etmek için çift boşlukları kaldırabilir ve dizedeki sayıları sayabilirsiniz. Stringr ve rm_white
{ qdapRegex } kullanın
str_count(rm_white(s), " ") +1
Çözüm 7, tek bir kelime olması durumunda doğru sonucu vermez. Gregexpr sonucundaki öğeleri saymamalısınız (eşleşmeyen yerlerde -1'dir), ancak> 0 olan öğeleri saymalısınız.
Ergo:
sapply(gregexpr("\\W+", str1), function(x) sum(x>0) ) + 1
str1
Sözcük olmayan karakterlerle başlar veya biterse bu yine de sorunlara neden olacaktır . Bu bir sorunsa, bu sürüm yalnızca sözcükler arasındaki boşlukları arayacaktır:sapply(gregexpr("\\b\\W+\\b", str, perl=TRUE), function(x) sum(x>0) ) + 1
Aşağıdaki işlevi ve normal ifadeyi, özellikle tek ve çift tireler ile uğraşırken, ilkinin genellikle bir kelime sonu olarak sayılmaması gereken, örneğin iyi bilinen hi-fi; çift tire ise, parantez içindeki açıklamalar gibi, beyaz boşlukla sınırlı olmayan bir noktalama ayırıcısıdır.
txt <- "Don't you think e-mail is one word--and not two!" #10 words
words <- function(txt) {
length(attributes(gregexpr("(\\w|\\w\\-\\w|\\w\\'\\w)+",txt)[[1]])$match.length)
}
words(txt) #10 words
Stringi kullanışlı bir pakettir. Ancak bu örnekteki sözcükleri tire nedeniyle fazla sayar.
stringi::stri_count_words(txt) #11 words
ile stringr pakette, bir de döngü için aracılığıyla örneğin dizeleri bir vektör çapraz olabilir basit bir komut dosyası yazabilirsiniz.
Diyelimki
df $ metin
analiz etmek istediğimiz dizelerin bir vektörünü içerir. Öncelikle, mevcut dataframe df'ye aşağıdaki gibi ek sütunlar ekliyoruz:
df$strings = as.integer(NA)
df$characters = as.integer(NA)
Sonra aşağıdaki gibi dizelerin vektörü üzerinde bir for-döngü çalıştırıyoruz:
for (i in 1:nrow(df))
{
df$strings[i] = str_count(df$text[i], '\\S+') # counts the strings
df$characters[i] = str_count(df$text[i]) # counts the characters & spaces
}
Ortaya çıkan sütunlar: dizeler ve karakter , sözcük ve karakter sayılarını içerecek ve bu, bir dizi vektörü için tek seferde başarılacaktır.