Poner en mayúscula la primera letra de ambas palabras en una cadena de dos palabras

174

Digamos que tengo una cadena de dos palabras y quiero capitalizar ambas.

name <- c("zip code", "state", "final count")

El Hmiscpaquete tiene una función capitalizeque capitaliza la primera palabra, pero no estoy seguro de cómo capitalizar la segunda palabra. La página de ayuda paracapitalize no sugiere que pueda realizar esa tarea.

library(Hmisc)
capitalize(name)
# [1] "Zip code"    "State"       "Final count"

Quiero tener:

c("Zip Code", "State", "Final Count")

¿Qué pasa con las cadenas de tres palabras:

name2 <- c("I like pizza")
ATMathew
fuente

Respuestas:

172

La función base R para realizar la capitalización es toupper(x) . Desde el archivo de ayuda ?toupperhay una función que hace lo que necesita:

simpleCap <- function(x) {
  s <- strsplit(x, " ")[[1]]
  paste(toupper(substring(s, 1,1)), substring(s, 2),
      sep="", collapse=" ")
}

name <- c("zip code", "state", "final count")

sapply(name, simpleCap)

     zip code         state   final count 
   "Zip Code"       "State" "Final Count" 

Editar Esto funciona para cualquier cadena, independientemente del número de palabras:

simpleCap("I like pizza a lot")
[1] "I Like Pizza A Lot"
Andrie
fuente
11
Y si esto es útil para otros, recuerde que al poner la función tolower dentro de la función simpleCap también puede manejar todas las palabras con límite: es el código que puede tratar: <br/> nombre <- c ("george wasHINgton", "tom jefferson "," ABE LINCOLN ") simpleCap <- function (x) {s <- tolower (x) s <- strsplit (s," ") [[1]] paste (toupper (substring (s, 1,1)) , substring (s, 2), sep = "", collapse = "")} sapply (name, simpleCap)
MatthewR
¿Qué hay de los nombres con guiones? Como Smith-Jones o Al-Rayon, que podrían ingresarse como SMITH-JONES o al-rayon.
Hack-R
1
Puedes usar en paste0()lugar de paste(..., sep=""). Simplemente más corto
MERose
3
@merose Correcto, pero no en este caso, ya paste0 ()que no acepta el collapse = ...argumento
Andrie
3
@ Andrew, ¿sigue siendo correcto? paste0(c("a", "b"), collapse = ",")funciona bien para mi Tal vez esta es una característica reciente?
MichaelChirico
156

También hay una solución base-R incorporada para el caso del título:

tools::toTitleCase("demonstrating the title case")
## [1] "Demonstrating the Title Case"

o

library(tools)
toTitleCase("demonstrating the title case")
## [1] "Demonstrating the Title Case"
Petermeissner
fuente
3
Habiendo examinado un poco la fuente, muestra que la función trata de lograr el título del caso (que es algo más que todas las palabras comienzan con mayúscula) dejando que comience todas las palabras con mayúscula, excepto una colección de excepciones en inglés más probables (como por ejemplo c("all", "above", "after", "along", "also", "among", "any", "both", "can", "few", "it", "less", "log", "many", "may", "more", "over", "some", "their", "then", "this", "under", "until", "using", "von", "when", "where", "which", "will", "without", "yet", "you", "your"))
petermeissner
15
Puede que se sorprenda si espera que SOLO el carácter inicial se capitalice. tools::toTitleCase("HELLO")resultados en HELLO. Es posible que desee concluir esto tolowerprimero, así: lo tools::toTitleCase(tolower("HELLO"))que regresaHello
ddunn801
2
buena pinta - todavía es el título-caso-ishst que puedes llegar hasta ahora
petermeissner 05 de
¡Gracias! Esta solución funciona muy bien para la mayoría de los casos, excepto cuando hay abreviaturas de estados de EE. UU.
Tung
97

Haga coincidir una expresión regular que comienza al principio ^o después de un espacio [[:space:]]y es seguida por un carácter alfabético [[:alpha:]]. A nivel mundial (la g en gsub) reemplazar todos estos hechos con el inicio o en el espacio y la versión en mayúsculas del carácter alfabético emparejado emparejado, \\1\\U\\2. Esto tiene que hacerse con la coincidencia de expresiones regulares de estilo perl.

gsub("(^|[[:space:]])([[:alpha:]])", "\\1\\U\\2", name, perl=TRUE)
# [1] "Zip Code"    "State"       "Final Count"

En un poco más de detalle para el argumento de reemplazo gsub(), \\1dice 'usa la parte de hacer xcoincidir la primera sub-expresión', es decir, la parte de hacer xcoincidir (^|[[:spacde:]]). Del mismo modo, \\2dice usar la parte de xemparejar la segunda subexpresión ([[:alpha:]]). La \\Usintaxis se habilita usando perl=TRUE, y significa hacer que el siguiente carácter sea mayúscula. Entonces, para "Código postal", \\1es "Código postal", \\2es "código", \\U\\2es "Código" y\\1\\U\\2 es "Código postal".

La ?regexppágina es útil para comprender expresiones regulares, ?gsubpara armar cosas.

Martin Morgan
fuente
12
¡Bah! Originalmente seguí este camino, pero por error estaba usando \\uy me di por vencido antes de darme cuenta de que debería haberlo capitalizado ... algo irónico. Esto es lo que se me ocurrió, no examinado a fondo en casos extrañosgsub(pattern = "\\b([a-z])", replacement = "\\U\\1", name, perl = TRUE)
Chase
Traté de usar esto en los nombres de fila y funcionó una vez, pero no pude repetirlo.
dpel
Funciona tolower(name)si hay otras tapas
MichaelChirico
83

Use esta función del stringipaquete

stri_trans_totitle(c("zip code", "state", "final count"))
## [1] "Zip Code"      "State"       "Final Count" 

stri_trans_totitle("i like pizza very much")
## [1] "I Like Pizza Very Much"
bartektartanus
fuente
24
El paquete stringr (si el tidyverse es lo tuyo) envuelve el stri_tans_totitleen una función llamada str_to_title(). Es solo el stringi :: stri_trans_totitle () debajo de las cubiertas, pero podría ahorrar cargar otra biblioteca (que, en esencia, ya puede haber cargado), dependiendo de su flujo de trabajo.
crazybilly
50

Alternativa:

library(stringr)
a = c("capitalise this", "and this")
a
[1] "capitalise this" "and this"       
str_to_title(a)
[1] "Capitalise This" "And This"   
Brijesh
fuente
Atrezzo para la respuesta stringr! ¡Gracias!
Neal Barsch
21

Tratar:

require(Hmisc)
sapply(name, function(x) {
  paste(sapply(strsplit(x, ' '), capitalize), collapse=' ')
})
diliop
fuente
tenga en cuenta que Hmiscpuede anular plyrla summarizefunción como se menciona aquí: stackoverflow.com/a/35324305/288875
Andre Holzner
2
@AndreHolzner O al revés. Hmisces bastante mayor que plyr...
Joris Meys
16

Desde la página de ayuda para ?toupper:

.simpleCap <- function(x) {
    s <- strsplit(x, " ")[[1]]
    paste(toupper(substring(s, 1,1)), substring(s, 2),
          sep="", collapse=" ")
}


> sapply(name, .simpleCap)

zip code         state   final count 
"Zip Code"       "State" "Final Count"
Persecución
fuente
9

El paquete BBmiscahora contiene la función capitalizeStrings.

library("BBmisc")
capitalizeStrings(c("the taIl", "wags The dOg", "That Looks fuNny!")
    , all.words = TRUE, lower.back = TRUE)
[1] "The Tail"          "Wags The Dog"      "That Looks Funny!"
Puñal
fuente
6

Forma alternativa con subcadena y regexpr:

substring(name, 1) <- toupper(substring(name, 1, 1))
pos <- regexpr(" ", name, perl=TRUE) + 1
substring(name, pos) <- toupper(substring(name, pos, pos))
Greg L
fuente
4

También puede usar el paquete snakecase:

install.packages("snakecase")
library(snakecase)

name <- c("zip code", "state", "final count")
to_title_case(name)
#> [1] "Zip Code"    "State"       "Final Count"

# or 
to_upper_camel_case(name, sep_out = " ")
#> [1] "Zip Code"    "State"       "Final Count"

https://github.com/Tazinho/snakecase

Taz
fuente
2

Esto le da letras mayúsculas a todas las palabras principales

library(lettercase)
xString = str_title_case(xString)
Cole Davis
fuente
No funciona perfectamente> lettercase::str_title_case("HEY HELLO") [1] "HEY HELLO"
Tung
Sí, sugeriría usar tolower (x) primero. También cometí un error al decir 'todas las palabras principales'; Esta función funciona en todas las palabras.
Cole Davis
Otra opción: biblioteca (Hmisc) # función de capitalización
Cole Davis