2015-09-24 11 views
5

Ho un vettore di nomi (umani), il tutto in maiuscolo:Decapitalize nomi umani (che rappresentano il 'e -)

names <- c("FRIEDRICH SCHILLER", "FRANK O'HARA", "HANS-CHRISTIAN ANDERSEN") 

Per decapitalize (capitalizzare le prime lettere solo) finora, ero utilizzando

simpleDecap <- function(x) { 
    s <- strsplit(x, " ")[[1]] 
    paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=" ") 
    } 
sapply(names, simpleDecap, USE.NAMES=FALSE) 
# [1] "Friedrich Schiller"   "Frank O'hara"   "Hans-christian Andersen" 

ma voglio anche rendere conto per ' e -. L'utilizzo di s <- strsplit(x, " |\\'|\\-")[[1]] ovviamente trova le lettere giuste, ma poi nel collasso ' e - si perdono. Quindi, ho cercato

simpleDecap2 <- function(x) { 
    for (char in c(" ", "\\-", "\\'")){ 
    s <- strsplit(x, char)[[1]] 
    x <-paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=char) 
    } return x 
    } 

sapply (nomi, simpleDecap, USE.NAMES = FALSE)

ma che è ancora peggio, naturalmente, in quanto i risultati sono divisi l'uno dopo l'altro:

sapply(names, simpleDecap2, USE.NAMES=FALSE) 
# [1] "Friedrich schiller"  "Frank o'Hara"   "Hans-christian andersen" 

Penso che l'approccio giusto divida in base allo s <- strsplit(x, " |\\'|\\-")[[1]], ma il problema è il paste=.

risposta

6

Questo sembra funzionare, utilizzando Perl espressioni regolari compatibili:

gsub("\\b(\\w)([\\w]+)", "\\1\\L\\2", names, perl = TRUE) 

\L trasforma il seguente gruppo di partita in minuscolo.

+1

amore la concisione * e * incomprensibilità di perl-regexp :-) –

+0

@CarlWitthoft Non sono affatto d'accordo con questo. Come qualsiasi altra lingua, devono essere apprese, ma per quello che esprimono sono molto semplici e comprensibili. L'affermazione generale che le regex sono incomprensibili è un'enorme canard: equivalente, il codice di analisi manuale è quasi sempre più complesso e difficile da capire. Usare la parola "incomprensibile" per questo è davvero fuorviante. –

+1

È uno scherzo divertente al meme che perl stesso permette uno stile di programmazione che rende il concorso c-code offuscato pallido al confronto. Ovviamente la regex è * la * via da seguire per la manipolazione delle stringhe. –

0

Anche se sono d'accordo che regexp Perl è la soluzione migliore, ma l'approccio simpleDecap2 non è poi così lontano dal lavoro.

simpleDecap3 <- function(x) { 
    x <- tolower(x) 
    for (char in c(" ", "-", "'")){ 
     s <- strsplit(x, char)[[1]] 
     x <-paste0(toupper(substring(s, 1,1)), substring(s, 2), collapse=char) 
    } 
    x 
} 

Cioè, girare il nome completo in minuscolo e poi in maiuscolo la prima lettera dopo "", "-", o "'". Non è bello come il regexp e molto probabilmente non così robusto, ma ottiene il lavoro fatto con solo piccole modifiche dal codice originale.

+0

Questo restituisce solo il primo valore. –

+0

Sì, ha lo stesso formato di 'simpleDecap2', è necessario chiamarlo' sapply (nomi, simpleDecap3, USE.NAMES = FALSE) '. – DGKarlsson