Как ограничить функцию «grepl» поиском строки только в одном столбце?

#r #string #grepl

#r #строка #grepl

Вопрос:

Я работаю с очень большим набором данных и пытаюсь извлечь небольшую строку только из одного столбца (переменной) из 47, используя grepl функцию. Вот код, который я использовал,

 x<-ebd_whbnut_relJun.2020[grepl("migrat", ebd_whbnut_relJun.2020[["SPECIES.COMMENTS"]]),]
  

в котором я пытаюсь извлечь любое упоминание строки «migrat’а» из только столбца «SPECIES.КОММЕНТАРИИ». «ebd_whbnut_relJun.2020» — это имя файла.

Я запустил код и получил 49 записей, но он вернулся как «49 объектов из 47 переменных». Некоторые записи содержали только записи из правильного столбца, но другие, по-видимому, содержали информацию из множества других столбцов. Из-за этого я не смог экспортировать данные в Excel и выдал сообщение об ошибке «Ошибка в libxlsxwriter: ‘Строка превышает установленный в Excel лимит в 32 767 символов».

Является ли это слишком примитивным и широким использованием функции grepl, или это что-то столь же простое, как пропущенная запятая / скобка?

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

1. если вы хотите захватить только столбец SPECIES.COMMENTS , укажите его ebd_whbnut_relJun.2020[grepl("migrat", ebd_whbnut_relJun.2020[["SPECIES.COMMENTS"]]),"SPECIES.COMMENTS"]

2. Ваш код переводится следующим образом: верните всю таблицу, где столбец «комментарии к видам» содержит «миграцию».

3. Возможно, короче, используя grep("migrat", ebd_whbnut_relJun.2020[["SPECIES.COMMENTS"]], value = TRUE) .

Ответ №1:

Я продемонстрирую некоторые методы, используя diamonds dataset из ggplot2 (хотя в остальном пакет не требуется).

 data("diamonds", package = "ggplot2")
dat <- as.data.frame(head(diamonds))
dat
#   carat       cut color clarity depth table price    x    y    z
# 1  0.23     Ideal     E     SI2  61.5    55   326 3.95 3.98 2.43
# 2  0.21   Premium     E     SI1  59.8    61   326 3.89 3.84 2.31
# 3  0.23      Good     E     VS1  56.9    65   327 4.05 4.07 2.31
# 4  0.29   Premium     I     VS2  62.4    58   334 4.20 4.23 2.63
# 5  0.31      Good     J     SI2  63.3    58   335 4.34 4.35 2.75
# 6  0.24 Very Good     J    VVS2  62.8    57   336 3.94 3.96 2.48
grep("Good", dat$cut, value = TRUE)
# [1] "Good"      "Good"      "Very Good"
dat$cut[ grepl("Good", dat$cut) ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal
dat[ grepl("Good", dat$cut), "cut" ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal
  

Обратите внимание, что если вы используете tbl_df или data.table , то выделение столбца ведет себя немного по-другому:

 as_tibble(dat)[ grepl("Good", dat$cut), "cut" ]
# # A tibble: 3 x 1
#   cut      
#   <ord>    
# 1 Good     
# 2 Good     
# 3 Very Good
as.data.table(dat)[ grepl("Good", dat$cut), "cut" ]
#          cut
# 1:      Good
# 2:      Good
# 3: Very Good
  

И на самом деле вы можете имитировать это и в base R таким образом, чтобы это также предполагало исправление:

 dat[ grepl("Good", dat$cut), "cut", drop = FALSE ]
#         cut
# 3      Good
# 5      Good
# 6 Very Good
as_tibble(dat)[ grepl("Good", dat$cut), "cut", drop = TRUE ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal
  

data.table немного отличается, но если вы пытаетесь это сделать, то вы уже знаете, что:

 as.data.table(dat)[ grepl("Good", cut), cut ]
# [1] Good      Good      Very Good
# Levels: Fair < Good < Very Good < Premium < Ideal
  

Данные, на случай, если у вас их нет ggplot2 :

 structure(list(carat = c(0.23, 0.21, 0.23, 0.29, 0.31, 0.24), 
    cut = structure(c(5L, 4L, 2L, 4L, 2L, 3L), .Label = c("Fair", 
    "Good", "Very Good", "Premium", "Ideal"), class = c("ordered", 
    "factor")), color = structure(c(2L, 2L, 2L, 6L, 7L, 7L), .Label = c("D", 
    "E", "F", "G", "H", "I", "J"), class = c("ordered", "factor"
    )), clarity = structure(c(2L, 3L, 5L, 4L, 2L, 6L), .Label = c("I1", 
    "SI2", "SI1", "VS2", "VS1", "VVS2", "VVS1", "IF"), class = c("ordered", 
    "factor")), depth = c(61.5, 59.8, 56.9, 62.4, 63.3, 62.8), 
    table = c(55, 61, 65, 58, 58, 57), price = c(326L, 326L, 
    327L, 334L, 335L, 336L), x = c(3.95, 3.89, 4.05, 4.2, 4.34, 
    3.94), y = c(3.98, 3.84, 4.07, 4.23, 4.35, 3.96), z = c(2.43, 
    2.31, 2.31, 2.63, 2.75, 2.48)), row.names = c(NA, -6L), class = "data.frame")