Zamień na wielką pierwszą literę obu słów w ciągu dwóch słów


174

Powiedzmy, że mam ciąg składający się z dwóch słów i chcę w obu z nich pisać wielką literą.

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

HmiscPakiet posiada funkcję capitalize, która kapitalizowane pierwsze słowo, ale nie jestem pewien jak zdobyć drugie słowo wielką literą. Strona pomocy dla capitalizenie sugeruje, że może wykonać to zadanie.

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

Chcę dostać:

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

A co z ciągami składającymi się z trzech słów:

name2 <- c("I like pizza")

Odpowiedzi:


172

Podstawową funkcją R do wykonywania wielkich liter jest toupper(x). Z pliku pomocy ?toupperjest funkcja, która robi to, czego potrzebujesz:

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" 

Edytuj Działa to dla dowolnego ciągu, niezależnie od liczby słów:

simpleCap("I like pizza a lot")
[1] "I Like Pizza A Lot"

11
A jeśli jest to pomocne dla innych, pamiętaj, że umieszczając funkcję tolower wewnątrz funkcji simpleCap, możesz również poradzić sobie ze wszystkimi słowami z wielkimi literami: czy kod, który możesz sobie poradzić: <br/> nazwa <- c ("george wasHINgton", "tom jefferson "," ABE LINCOLN ") simpleCap <- function (x) {s <- tolower (x) s <- strsplit (s," ") [[1]] wklej (toupper (podciąg (s, 1,1)) , sUBSTRING (s, 2), sep = "zapaść", „=„)} sapply (nazwa simpleCap)
MatthewR

A co z nazwami z łącznikami? Jak Smith-Jones czy Al-Rayon, które można wpisać jako SMITH-JONES lub al-rayon.
Hack-R

1
Możesz użyć paste0()zamiast paste(..., sep=""). Po prostu krótszy.
MERose

3
@merose Poprawne, ale nie w tym przypadku, ponieważ paste0 ()nie akceptuje collapse = ...argumentu
Andrie

3
@ Andrie, czy to nadal jest poprawne? paste0(c("a", "b"), collapse = ",")dla mnie działa dobrze. Może to nowa funkcja?
MichaelChirico

156

Istnieje również wbudowane rozwiązanie base-R dla przypadku tytułu:

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

lub

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

3
Przyjrzawszy się trochę źródłu, pokazuje, że funkcja próbuje uzyskać wielkość liter w tytule (co jest czymś innym niż wszystkie słowa zaczynające się wielką literą), pozwalając rozpoczynać wszystkie słowa dużymi literami, z wyjątkiem zbioru angielskich najprawdopodobniej wyjątków (takich jak np. 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
Możesz być zaskoczony, jeśli oczekujesz, że TYLKO początkowy znak będzie pisany wielką literą. tools::toTitleCase("HELLO")powoduje HELLO. Możesz chcieć to tolowernajpierw owinąć , tak jak to: tools::toTitleCase(tolower("HELLO"))co zwracaHello
ddunn801

2
dobry ppint - wciąż jest to tytułowy przypadek, który można osiągnąć do tej pory
petermeissner

Dzięki! To rozwiązanie działa świetnie w większości przypadków, z wyjątkiem przypadków, gdy istnieją skróty stanów USA
Tung,

97

Dopasuj wyrażenie regularne rozpoczynające się na początku ^lub po spacji [[:space:]]i zakończone znakiem alfabetu [[:alpha:]]. Globalnie (G w gsub) zastąpić wszystkie wystąpienia z dopasowaną rozpoczynających lub przestrzeń i wersji wyższej przypadek dopasowane charakterem alfabetycznej \\1\\U\\2. Należy to zrobić za pomocą dopasowywania wyrażeń regularnych w stylu perla.

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

W nieco bardziej szczegółowo za argument do zastąpienia gsub(), \\1mówi „użyj część xdopasowanie akapicie pierwszym wyrażenie”, czyli część xdopasowywania (^|[[:spacde:]]). Podobnie, \\2mówi, używa części xdopasowania drugiego wyrażenia podrzędnego ([[:alpha:]]). \\UJest włączona przy użyciu składni perl=TRUE, a środki do ich następnego znaku wielkich liter. Tak więc „Kod pocztowy” \\1to „Kod pocztowy”, \\2„Kod”, \\U\\2„Kod” i \\1\\U\\2„Kod pocztowy”.

?regexpStrona jest bardzo pomocna w zrozumieniu wyrażeń regularnych, ?gsubna oddanie rzeczy razem.


12
ba! Początkowo poszedłem tą ścieżką, ale omyłkowo \\uużyłem i zrezygnowałem, zanim zdałem sobie sprawę, że powinienem to wykorzystać ... nieco ironiczne. Oto, co wymyśliłem, nie do końca sprawdzone pod kątem dziwnych przypadków piłkigsub(pattern = "\\b([a-z])", replacement = "\\U\\1", name, perl = TRUE)
Chase,

Próbowałem użyć tego w nazwach wierszy i raz zadziałało, ale nie mogłem tego powtórzyć.
dpel

Działa, tolower(name)jeśli są inne czapki
MichaelChirico

83

Użyj tej funkcji z stringipakietu

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
Pakiet stringr (jeśli tidyverse jest twoją rzeczą) opakowuje stri_tans_totitlefunkcję o nazwie str_to_title(). To tylko stringi :: stri_trans_totitle () pod okładkami, ale może zaoszczędzić ładowanie innej biblioteki (którą w zasadzie możesz już załadować), w zależności od przepływu pracy.
crazybilly

50

Alternatywny:

library(stringr)
a = c("capitalise this", "and this")
a
[1] "capitalise this" "and this"       
str_to_title(a)
[1] "Capitalise This" "And This"   

Rekwizyty za odpowiedź! Dzięki!
Neal Barsch


16

Ze strony pomocy dla ?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

Pakiet BBmisczawiera teraz funkcję 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

Alternatywny sposób z podciągiem i wyrażeniem regularnym:

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

4

Możesz również skorzystać z pakietu wężowego:

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

To daje wielkie litery do wszystkich głównych słów

library(lettercase)
xString = str_title_case(xString)

Nie działa idealnie> lettercase::str_title_case("HEY HELLO") [1] "HEY HELLO"
Tung

Tak, sugerowałbym najpierw użycie tolower (x). Popełniłem również błąd, mówiąc „wszystkie najważniejsze słowa”; ta funkcja działa na wszystkich słowach.
Cole Davis,

Inna opcja: biblioteka (Hmisc) # funkcja wielkich liter
Cole Davis
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.