Команда Gsub для замены всех пробелов запятой и пробелом ( » ,»), за исключением некоторых слов с R

#r #regex #gsub

Вопрос:

У меня есть фрейм данных со столбцом, содержащим округа Калифорнии в каждой ячейке, разделенной пробелом. Я хотел бы добавить запятую и пробел после каждого, однако я не могу просто вставить каждый пробел в запятую и пробел (т. Е. gsub(«s»,»,s», текст)), Так как некоторые округа в Калифорнии имеют два названия (например, Лос-Анджелес, Сан-Франциско и т. Д.)

К счастью, все округа, состоящие из двух слов, имеют общие первые слова, поэтому я хотел бы написать gsub, который сохраняет пространство в этих округах без добавления запятой. Я приложил примеры данных, а также то, как я хотел бы, чтобы выглядела окончательная форма. Например, с этими данными я хотел бы добавить запятую и пробел, за исключением «El», «San» и «Del».

Примеры данных:

 c("Lassen Modoc Nevada Plumas Shasta Sierra Siskiyou Butte Placer", 
"Del Norte Humboldt Trinity Mendocino Sonoma", "Glenn Sutter Tehama Yuba Butte Colusa", 
"Lake Napa Yolo Colusa Sonoma Solano", "Madera Amador Tuolumne Calaveras Mariposa Mono Alpine El Dorado Placer", 
"El Dorado Placer Sacramento", "Sacramento Yolo", "Sacramento", 
"Sacramento San Joaquin", "Marin Sonoma")
 

Желаемый результат:

 c("Lassen, Modoc, Nevada, Plumas, Shasta, Sierra, Siskiyou, Butte, Placer", 
  "Del Norte, Humboldt, Trinity, Mendocino, Sonoma", "Glenn, Sutter, Tehama, Yuba, Butte, Colusa", 
  "Lake, Napa, Yolo, Colusa, Sonoma, Solano", "Madera, Amador, Tuolumne, Calaveras, Mariposa, Mono, Alpine, El Dorado, Placer", 
  "El Dorado, Placer, Sacramento", "Sacramento, Yolo", "Sacramento", 
  "Sacramento, San Joaquin", "Marin, Sonoma")
 

Ответ №1:

Учитывая, что вы знаете, что ищете только округа Калифорнии, один «простой» способ-просто заменить только пробелы, которые встречаются после округа Калифорния. Чтобы получить это регулярное выражение, я просто объединил названия округов CA вместе с | и добавил пробел. Это gsub заменит любое название округа, за которым следует пробел с тем же названием округа ( \1 ), запятую и пробел.

 ca_regex <- "(Los Angeles|San Diego|Orange|Riverside|San Bernardino|Santa Clara|Alameda|Sacramento|Contra Costa|Fresno|Kern|San Francisco|Ventura|San Mateo|San Joaquin|Stanislaus|Sonoma|Tulare|Santa Barbara|Solano|Monterey|Placer|San Luis Obispo|Santa Cruz|Merced|Marin|Butte|Yolo|El Dorado|Imperial|Shasta|Madera|Kings|Napa|Humboldt|Nevada|Sutter|Mendocino|Yuba|Lake|Tehama|San Benito|Tuolumne|Calaveras|Siskiyou|Amador|Lassen|Glenn|Del Norte|Colusa|Plumas|Inyo|Mariposa|Mono|Trinity|Modoc|Sierra|Alpine) "

input <- c(
  "Lassen Modoc Nevada Plumas Shasta Sierra Siskiyou Butte Placer",
  "Del Norte Humboldt Trinity Mendocino Sonoma", "Glenn Sutter Tehama Yuba Butte Colusa",
  "Lake Napa Yolo Colusa Sonoma Solano", "Madera Amador Tuolumne Calaveras Mariposa Mono Alpine El Dorado Placer",
  "El Dorado Placer Sacramento", "Sacramento Yolo", "Sacramento",
  "Sacramento San Joaquin", "Marin Sonoma"
)

gsub(ca_regex, "\1, ", input)
#>  [1] "Lassen, Modoc, Nevada, Plumas, Shasta, Sierra, Siskiyou, Butte, Placer"        
#>  [2] "Del Norte, Humboldt, Trinity, Mendocino, Sonoma"                               
#>  [3] "Glenn, Sutter, Tehama, Yuba, Butte, Colusa"                                    
#>  [4] "Lake, Napa, Yolo, Colusa, Sonoma, Solano"                                      
#>  [5] "Madera, Amador, Tuolumne, Calaveras, Mariposa, Mono, Alpine, El Dorado, Placer"
#>  [6] "El Dorado, Placer, Sacramento"                                                 
#>  [7] "Sacramento, Yolo"                                                              
#>  [8] "Sacramento"                                                                    
#>  [9] "Sacramento, San Joaquin"                                                       
#> [10] "Marin, Sonoma"
 

Если вы хотите, вы можете использовать отрицательный lookbehind ( (?<!) ), чтобы использовать более короткий шаблон. Этот вариант использует только префиксные слова из списка округов CA и заменяет только пробелы, которые не идут после одного из них. Я думаю, что об этом немного сложнее рассуждать и сложнее придумать (например, при первом размещении я забыл о округе Сан-Луис-Обиспо с двумя интервалами).

 gsub("(?<!Los|San|Santa|Contra|El|Del|Luis) ", ", ", input, perl = TRUE)
#>  [1] "Lassen, Modoc, Nevada, Plumas, Shasta, Sierra, Siskiyou, Butte, Placer"        
#>  [2] "Del Norte, Humboldt, Trinity, Mendocino, Sonoma"                               
#>  [3] "Glenn, Sutter, Tehama, Yuba, Butte, Colusa"                                    
#>  [4] "Lake, Napa, Yolo, Colusa, Sonoma, Solano"                                      
#>  [5] "Madera, Amador, Tuolumne, Calaveras, Mariposa, Mono, Alpine, El Dorado, Placer"
#>  [6] "El Dorado, Placer, Sacramento"                                                 
#>  [7] "Sacramento, Yolo"                                                              
#>  [8] "Sacramento"                                                                    
#>  [9] "Sacramento, San Joaquin"                                                       
#> [10] "Marin, Sonoma"
 

Комментарии:

1. Если вы используете второй вариант, обратите внимание, что я только что изменил его, чтобы справиться с Сан-Луис-Обиспо.

Ответ №2:

 gsub('(\w{4,}) ', '\1, ', vec)

 [1] "Lassen, Modoc, Nevada, Plumas, Shasta, Sierra, Siskiyou, Butte, Placer"        
 [2] "Del Norte, Humboldt, Trinity, Mendocino, Sonoma"                               
 [3] "Glenn, Sutter, Tehama, Yuba, Butte, Colusa"                                    
 [4] "Lake, Napa, Yolo, Colusa, Sonoma, Solano"                                      
 [5] "Madera, Amador, Tuolumne, Calaveras, Mariposa, Mono, Alpine, El Dorado, Placer"
 [6] "El Dorado, Placer, Sacramento"                                                 
 [7] "Sacramento, Yolo"                                                              
 [8] "Sacramento"                                                                    
 [9] "Sacramento, San Joaquin"                                                       
[10] "Marin, Sonoma"           
 

Комментарии:

1. Это подходит для набора входных данных OP, но разделит Санта-Клару и Контра Коста, так как их первые слова состоят более чем из 4 букв.