Вопрос по r, string – Усечение конца строки в R после символа, который может присутствовать ноль или более раз

8

У меня есть следующие данные:

temp<-c("AIR BAGS:FRONTAL" ,"SERVICE BRAKES HYDRAULIC:ANTILOCK",
    "PARKING BRAKE:CONVENTIONAL",
    "SEATS:FRONT ASSEMBLY:POWER ADJUST",
    "POWER TRAIN:AUTOMATIC TRANSMISSION",
    "SUSPENSION",
    "ENGINE AND ENGINE COOLING:ENGINE",
    "SERVICE BRAKES HYDRAULIC:ANTILOCK",
    "SUSPENSION:FRONT",
    "ENGINE AND ENGINE COOLING:ENGINE",
    "VISIBILITY:WINDSHIELD WIPER/WASHER:LINKAGES")

Я хотел бы создать новый вектор, который сохраняет только текст перед первым & quot;: & quot; в случаях, когда & quot;: & quot; присутствует, и целое слово, когда & quot; & quot; нет

Я пытался использовать:

temp=data.frame(matrix(unlist(str_split(temp,pattern=":",n=2)), 
+                        ncol=2, byrow=TRUE))

но это не работает в тех случаях, когда нет & quot; & quot;

Я знаю, что этот вопрос очень похож на: обрезать строку из определенного символа в R, который использовал:

sub("^[^.]*", "", x)

Но я не очень знаком с регулярными выражениями и изо всех сил пытался перевернуть этот пример, чтобы сохранить только начало строки.

Ваш Ответ

5   ответов
1

в этом случае

yy<-c("AIR BAGS:FRONTAL",
"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"PARKING BRAKE:CONVENTIONAL",
"SEATS:FRONT ASSEMBLY:POWER ADJUST",
"POWER TRAIN:AUTOMATIC TRANSMISSION",
"SUSPENSION",
"ENGINE AND ENGINE COOLING:ENGINE",
"SERVICE BRAKES HYDRAULIC:ANTILOCK",
"SUSPENSION:FRONT",
"ENGINE AND ENGINE COOLING:ENGINE",
"VISIBILITY:WINDSHIELD WIPER/WASHER:LINKAGES")
yy<-gsub("([^:]*).*","\\1",yy)
yy

может работать на тебя

9

Другой подход заключается в поиске первого & quot;: & quot; и заменить его и что-нибудь после этого ничем:

yy <- sub(":.*$", "", yy )

Если нет & quot;: & quot; затем ничего не подставляется, и вы получаете всю исходную строку. Если есть & quot;: & quot; затем первый сопоставляется со всем после него, затем его заменяют ничем (& quot; & quot;), которое удаляет его и оставляет все до этого первого двоеточия.

15

Вы можете решить это с помощью простого регулярного выражения:

sub("(.*?):.*", "\\1", x)
 [1] "AIR BAGS"                  "SERVICE BRAKES HYDRAULIC"  "PARKING BRAKE"             "SEATS"                    
 [5] "POWER TRAIN"               "SUSPENSION"                "ENGINE AND ENGINE COOLING" "SERVICE BRAKES HYDRAULIC" 
 [9] "SUSPENSION"                "ENGINE AND ENGINE COOLING" "VISIBILITY"     

Как работает регулярное выражение:

  • "(.*?):.*" Look for a repeated set of any characters .* but modify it with ? to not be greedy. This should be followed by a colon and then any character (repeated)
  • Substitute the entire string with the bit found inside the parentheses - "\\1"

Нужно понимать, что любое совпадение с регулярным выражением является жадным по умолчанию. Изменяя его, чтобы он был не жадным, первое совпадение с образцом не может включать двоеточие, так как первый символ после скобок является двоеточием. Регулярное выражение после двоеточия возвращается к значению по умолчанию, то есть к жадному алгоритму.

Error: User Rate Limit Exceeded Tony M.
3

Извините, что добавил это как ответ. В ответ на принятые времена:

> yy<-rep("foo1:bar1",times=100000)
> system.time(yy1<-sapply(strsplit(yy,":"),'[',1))
   user  system elapsed 
   0.26    0.00    0.27 
> 
> system.time(yy2<-sub("(.*?):.*", "\\1", yy))
   user  system elapsed 
    0.1     0.0     0.1 
> 
> system.time(yy3 <- sub(":.*$", "", yy ))
   user  system elapsed 
   0.08    0.00    0.07 
> 
> system.time(yy4<-gsub("([^:]*).*","\\1",yy))
   user  system elapsed 
   0.09    0.00    0.09 

Регулярные выражения примерно эквивалентны, strsplit занимает немного больше времени

Error: User Rate Limit Exceeded
3

Работает ли это (предполагая, что ваши данные находятся в символьном векторе):

x <- c('foobar','foo:bar','foo1:bar1 foo:bar','foo bar')
> sapply(str_split(x,":"),'[',1)
[1] "foobar"  "foo"     "foo1"    "foo bar"
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы