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")
ATMathew
źródło

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"
Andrie
źródło
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"
petermeissner
źródło
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.

Martin Morgan
źródło
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"
bartektartanus
źródło
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"   
Brijesh
źródło
Rekwizyty za odpowiedź! Dzięki!
Neal Barsch
21

Próbować:

require(Hmisc)
sapply(name, function(x) {
  paste(sapply(strsplit(x, ' '), capitalize), collapse=' ')
})
diliop
źródło
Należy pamiętać, że Hmiscmoże zastąpić plyr„s summarizefunkcja jak wspomniano tutaj: stackoverflow.com/a/35324305/288875
Andre Holzner
2
@AndreHolzner Albo na odwrót. Hmiscjest trochę starszy niż plyr...
Joris Meys
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"
Pościg
źródło
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!"
Sztylet
źródło
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))
greg L.
źródło
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

Taz
źródło
2

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

library(lettercase)
xString = str_title_case(xString)
Cole Davis
źródło
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