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")

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"

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"

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.


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"

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"   

Atrezzo para la respuesta stringr! ¡Gracias!
Neal Barsch


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"

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!"

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

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


2

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

library(lettercase)
xString = str_title_case(xString)

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.