¿Existe una función para contar el número de palabras en una cadena? Por ejemplo:
str1 <- "How many words are in this sentence"
para devolver un resultado de 7.
r
string
word-count
Juan
fuente
fuente
Respuestas:
Puede utilizar
strsplit
ysapply
funcionessapply(strsplit(str1, " "), length)
fuente
lengths
función algo nueva en la base R, que encuentra la longitud de cada elemento:lengths(strsplot(str, " "))
Utilice el símbolo de expresión regular
\\W
para hacer coincidir los caracteres que no son palabras, utilizando+
para indicar uno o más en una fila, junto congregexpr
para buscar todas las coincidencias en una cadena. Las palabras son el número de separadores de palabras más 1.lengths(gregexpr("\\W+", str1)) + 1
Este fallará con cadenas en blanco al principio o al final del vector de caracteres, cuando una "palabra" no satisface
\\W
's noción de no-palabra (se podría trabajar con otras expresiones regulares,\\S+
,[[:alpha:]]
, etc., pero siempre habrá ser casos extremos con un enfoque de expresiones regulares), etc. Es probable que sea más eficiente que lasstrsplit
soluciones, que asignarán memoria para cada palabra. Las expresiones regulares se describen en?regex
.Actualización Como se señaló en los comentarios y en una respuesta diferente de @Andri, el enfoque falla con (cero) y cadenas de una palabra, y con puntuación final
str1 = c("", "x", "x y", "x y!" , "x y! z") lengths(gregexpr("[A-z]\\W+", str1)) + 1L # [1] 2 2 2 3 3
Muchas de las otras respuestas también fallan en estos o casos similares (p. Ej., Espacios múltiples). Creo que la advertencia de mi respuesta sobre la "noción de una palabra" en la respuesta original cubre problemas con la puntuación (solución: elija una expresión regular diferente, por ejemplo,
[[:space:]]+
), pero los casos de una palabra y cero son un problema; La solución de @ Andri no distingue entre cero y una palabra. Así que adoptar un enfoque 'positivo' para encontrar palabras que uno podríasapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
Llevando a
sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0)) # [1] 0 1 2 2 3
Nuevamente, la expresión regular podría refinarse para diferentes nociones de "palabra".
Me gusta el uso de
gregexpr()
porque es eficiente en la memoria. Una alternativa al usarstrsplit()
(como @ user813966, pero con una expresión regular para delimitar palabras) y hacer uso de la noción original de delimitar palabras eslengths(strsplit(str1, "\\W+")) # [1] 0 1 2 2 3
Esto necesita asignar nueva memoria para cada palabra que se crea y para la lista intermedia de palabras. Esto podría resultar relativamente caro cuando los datos son "grandes", pero probablemente sea eficaz y comprensible para la mayoría de los propósitos.
fuente
str1 <- c('s ss sss ss', "asdf asd hello this is your life!"); sapply(gregexpr("\\W+", str1), length) + 1
devuelve4
y8
. Primero correcto, segundo demasiado. Creo que está contando la puntuación.sapply(gregexpr("\\W+", "word"), length) + 1
devuelve 2La forma más sencilla sería:
require(stringr) str_count("one, two three 4,,,, 5 6", "\\S+")
... contando todas las secuencias en caracteres sin espacios (
\\S+
).Pero, ¿qué pasa con una pequeña función que nos permite también decidir qué tipo de palabras nos gustaría contar y cuáles funcionan también en vectores completos ?
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
fuente
Uso la
str_count
función de lastringr
biblioteca con la secuencia de escape\w
que representa:Ejemplo:
> str_count("How many words are in this sentence", '\\w+') [1] 7
De todas las otras 9 respuestas que pude probar, solo dos (por Vincent Zoonekynd y por petermeissner) funcionaron para todas las entradas presentadas aquí hasta ahora, pero también requieren
stringr
.Pero solo esta solución funciona con todas las entradas presentadas hasta ahora, más entradas como
"foo+bar+baz~spam+eggs"
o"Combien de mots sont dans cette phrase ?"
.Punto de referencia:
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))
Salida:
6 10 10 8 9 9 7 6 6 11
fuente
'[\\w\']+'
(no se puede probar, por lo que puede aplicarse xkcd.com/1638 ); de lo contrario, no estoy seguro de si regex es lo suficientemente potente como para manejarlo en el caso general :)'\\w+(\'\\w{1,2})?'
podría ser una buena solución.o'clock
yfriggin'
podrías hacer\w+('\w*)?
(no sé si hay palabras que comiencen con apóstrofe). Para manejar adicionalmente las horas, puede intentar hacerlas coincidir\d?\d:\d\d|\w+('\w*)?
o hacer algo aún más complicado según sus necesidades. Pero esto se trata cada vez menos de R y más de cómo define una palabra, por lo que tal vez pueda publicar una pregunta separada para cubrir sus necesidades específicas.str2 <- gsub(' {2,}',' ',str1) length(strsplit(str2,' ')[[1]])
Se
gsub(' {2,}',' ',str1)
asegura de que todas las palabras estén separadas por un solo espacio, reemplazando todas las apariciones de dos o más espacios con un espacio.El
strsplit(str,' ')
divide la frase en cada espacio y devuelve el resultado en una lista. El[[1]]
toma el vector de palabras de esa lista. Lalength
cuenta hasta cuántas palabras.> 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
fuente
Puede usar
str_match_all
, con una expresión regular que identifique sus palabras. A continuación se trabaja con espacios iniciales, finales y duplicados.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]])
fuente
Prueba esta función del
stringi
paqueterequire(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
fuente
Puede usar la función wc en la biblioteca qdap :
> str1 <- "How many words are in this sentence" > wc(str1) [1] 7
fuente
Puede eliminar los espacios dobles y contar el número de
" "
en la cadena para obtener el recuento de palabras. Utilice stringr yrm_white
{ qdapRegex }str_count(rm_white(s), " ") +1
fuente
Prueba esto
length(unlist(strsplit(str1," ")))
fuente
También del
stringi
paquete, la función directastri_count_words
stringi::stri_count_words(str1) #[1] 7
fuente
La solución 7 no da el resultado correcto en el caso de que solo haya una palabra. No solo debe contar los elementos en el resultado de gregexpr (que es -1 si no coincide), sino contar los elementos> 0.
Es decir:
sapply(gregexpr("\\W+", str1), function(x) sum(x>0) ) + 1
fuente
str1
comienza o termina con caracteres que no son palabras. Si eso es una preocupación, esta versión solo buscará espacios entre palabras:sapply(gregexpr("\\b\\W+\\b", str, perl=TRUE), function(x) sum(x>0) ) + 1
require(stringr) str_count(x,"\\w+")
estará bien con espacios dobles / triples entre palabras
Todas las demás respuestas tienen problemas con más de un espacio entre las palabras.
fuente
require (stringr)
Define una función muy simple
str_words <- function(sentence) { str_count(sentence, " ") + 1 }
Cheque
fuente
Utilizar
nchar
si se llama vector de cadenas
x
(nchar(x) - nchar(gsub(' ','',x))) + 1
Averigüe la cantidad de espacios y luego agregue uno
fuente
He encontrado que la siguiente función y expresión regular son útiles para el recuento de palabras, especialmente al tratar con guiones simples o dobles, donde el primero generalmente no debería contar como un salto de palabra, por ejemplo, bien conocido, de alta fidelidad; mientras que el guión doble es un delimitador de puntuación que no está delimitado por espacios en blanco, como ocurre con los comentarios entre paréntesis.
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 es un paquete útil. Pero cuenta en exceso las palabras en este ejemplo debido al guión.
stringi::stri_count_words(txt) #11 words
fuente
Con stringr paquete , también se puede escribir un script simple que pueda atravesar un vector de cadenas, por ejemplo, a través de un bucle for.
Digamos
contiene un vector de cadenas que nos interesa analizar. Primero, agregamos columnas adicionales al marco de datos existente df como se muestra a continuación:
df$strings = as.integer(NA) df$characters = as.integer(NA)
Luego ejecutamos un bucle for sobre el vector de cadenas de la siguiente manera:
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 }
Las columnas resultantes: cadenas y carácter contendrán los recuentos de palabras y caracteres y esto se logrará de una sola vez para un vector de cadenas.
fuente