grep
(и grepl
) не подходят для этого: вы не фильтрации на основе текстового содержимого. Вы (а) фильтруете на основе Faults
и (b) меняете текст в Class
.
Данные:
ds1 <- structure(list(Class = c("org.apache.tools.ant.taskdefs.Definer", "org.apache.tools.ant.taskdefs.Definer", "org.apache.tools.ant.taskdefs.Delete", "org.apache.tools.ant.taskdefs.Deltree", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.DependSet", "org.apache.tools.ant.taskdefs.Ear", "org.apache.tools.ant.taskdefs.Ear", "org.apache.tools.ant.taskdefs.Echo", "org.apache.tools.ant.Exec", "org.apache.tools.ant.Exec"),
Faults = c(2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L)),
.Names = c("Class", "Faults"), class = "data.frame", row.names = c(NA, -12L))
Фильтр по Faults
(вы уже это). Вам нужна только одна из этих двух команд, они оба делают то же самое; основные отличия заключаются в удобочитаемости (личном предпочтении) и производительности (вторая, в данном случае, занимает около 35% меньше времени, хотя, поскольку они оба измеряются в микросекундах, кажется, что глупо конкурировать).
ds2 <- subset(ds1, Faults == 2)
ds2 <- ds1[ds1$Faults == 2,]
Update Class
удалить последнее слово (и точка):
ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class)
ds2
# Class Faults
# 1 org.apache.tools.ant.taskdefs 2
# 2 org.apache.tools.ant.taskdefs 2
# 4 org.apache.tools.ant.taskdefs 2
# 5 org.apache.tools.ant.taskdefs 2
# 6 org.apache.tools.ant.taskdefs 2
# 7 org.apache.tools.ant.taskdefs 2
# 8 org.apache.tools.ant.taskdefs 2
# 9 org.apache.tools.ant.taskdefs 2
# 11 org.apache.tools.ant 2
# 12 org.apache.tools.ant 2
Примечание: это также может быть сделано с sub
вместо gsub
, но последний мой первый-достигните, так как большинство мои работы связаны с большими и повторяющимися регулярными выражениями. Главный (? Только) различие между ними состоит в том, что:
'sub' and 'gsub' perform replacement of the first and all matches respectively
(от ?sub
).
Я не знаю инструмента, который делает как фильтрация и изменение в одной команде (хотя возможно data.table
делает, я не знаю).
Аналогично решению @ egnha (то использует magrittr
), вот один с помощью dplyr
, что многие люди утверждают, очень легко читать и адаптироваться (при потенциальной стоимости исполнения):
library(dplyr)
ds2 <- ds1 %>%
filter(Faults == 2) %>%
mutate(Class = gsub("\\.[^.]*$", "", Class))
Поскольку я упомянул производительность, вот сравнение:
microbenchmark(indexing = { ds2 <- ds1[ds1$Faults == 2,]; ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class) },
subset = { ds2 <- subset(ds1, Faults == 2) ; ds2$Class <- gsub("\\.[^.]*$", "", ds2$Class) },
dplyr = { ds1 %>% filter(Faults == 2) %>% mutate(Class = gsub("\\.[^.]*$", "", Class)) })
# Unit: microseconds
# expr min lq mean median uq max neval
# indexing 71.841 87.7045 109.4496 104.2975 120.7075 269.493 100
# subset 102.473 115.6020 147.0108 139.1230 165.5620 287.726 100
# dplyr 1067.030 1156.3745 1323.1174 1225.4805 1351.2920 4270.308 100
Для записи dplyr
используется таким образом, не часто эта скорость бедных по сравнению с другими методами. Обычно не быстрее, но это не часто на порядок медленнее.
Будет ли «grepl» более уместным? – r2evans
Можете ли вы разрешить это с помощью 'grepl'? –
У '' /^([^\\.]+)/ '' есть одна серьезная проблема: вы используете разделители регулярных выражений '/', которые не должны использоваться в функциях R regex. Кроме того, когда вы избегаете символа '.' В классе символов, вы делаете его совместимым только с PCRE (больше не совместимым с TRE). Однако, чтобы получить строку перед последней точкой, вам понадобится ''^(. *) \\. "' (Тогда у вас есть захваченное значение внутри группы 1) или PCRE один '' ^. * (? = \ \.) "' (с 'perl = TRUE'). –