создать столбец data.table в трубе с помощью grepl - PullRequest
0 голосов
/ 04 октября 2018

Я ищу способ создания нового столбца data.table в конвейерной последовательности, используя grepl, ища любое вхождение определенной строки.

Я посмотрел здесь и здесь за помощь, и, кажется, есть много вопросов по этой теме, но, похоже, это не касается моей проблемы.

Кроме того, я могу неправильно понимать синтаксис data.tableи ссылаюсь на Эталонную семантику виньеток .У меня есть код ниже с двумя подходами, которые могут быть переданы по цепочке, но, кажется, не работают.Последняя опция, в которой столбец data.table создается в явном виде, кажется, работает, но мне интересно, может ли он быть соединен в цепочку.

Насколько я понимаю, использование lapply в data.table позволит применить функциюко всему столбцу (то есть sum, mean, na.approx, который я узнал из другого опубликованного вопроса), но не будет работать построчно.Кроме того, я могу применить функцию к каждой строке в данном столбце, используя new_col := function(x).Так что я бы подумал, что один из них сработает.

Я (только в некоторой степени) осознаю, что grepl ожидает одно значение, но предоставляется вектор, и я не уверен, как это исправить.

Любая помощь приветствуется, спасибо.

> library(data.table)
> 
> a = c("housefly",
+       "house fly",
+       "HOUSEFLY",
+       "HOUSE FLY")
> 
> dt = data.table(insect = c("housefly",
+                            "house fly",
+                            "HOUSEFLY",
+                            "HOUSE FLY",
+                            "dragonfly",
+                            "dragon fly"))
> 
> # does not work but I could put this in chain/pipe
> dt[, fly_check := sapply(.SD, grepl, paste(a, collapse = "|")), .SDcols = "insect"]
Warning message:
In FUN(X[[i]], ...) :
  argument 'pattern' has length > 1 and only the first element will be used
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly      TRUE
6: dragon fly      TRUE
> 
> # does not work but I could put this in chain/pipe
> dt[, fly_check := ifelse(grepl(insect, paste(a, collapse = "|")), TRUE, FALSE)]
Warning message:
In grepl(insect, paste(a, collapse = "|")) :
  argument 'pattern' has length > 1 and only the first element will be used
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly      TRUE
6: dragon fly      TRUE
> 
> # works but can't be chained/piped
> dt$fly_check = sapply(dt$insect, grepl, pattern = paste(a, collapse = "|"))
> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly     FALSE
6: dragon fly     FALSE

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Я думаю, что это просто простое применение %in% к a значениям

dt[ , fly_check := insect %in% a]

, что кажется более простым, чем применение grepl к свернутым a значениям в качестве шаблона.

dt[ , fly_check := grepl( paste0(a, collapse="|") , insect)]

> dt
       insect fly_check
1:   housefly      TRUE
2:  house fly      TRUE
3:   HOUSEFLY      TRUE
4:  HOUSE FLY      TRUE
5:  dragonfly     FALSE
6: dragon fly     FALSE

Полагаю, вы все еще можете выбрать стратегию grepl, если вы получили общность с ignore.case=TRUE или с необходимыми возможностями, предоставляемыми параметрами 'perl' или 'fixed'.

0 голосов
/ 04 октября 2018

Кажется, вы ищете это, хотя гораздо более простое решение дает @ chinsoon12 (в комментариях), который просто передает имя столбца напрямую:

Логика: в data.table, если вывызовите его, используя параметр .SD, это означает подмножество данных, которое также предполагает, что столбец передается не как вектор, а как объект data.table (следовательно, вы должны использовать Vectorize или другие операции), с другой стороны, если вы передадите егоНепосредственно как столбец, grepl без проблем работает с векторной структурой (решение @ Chinsoon12).

Вы можете проверить это , это очень поучительная ссылка.

dt[, fly_check := (Vectorize(grepl)(paste0(a, collapse = "|"),.SD)), .SDcols = c("insect")]

, которая приводит к:

#       insect fly_check
#1:   housefly      TRUE
#2:  house fly      TRUE
#3:   HOUSEFLY      TRUE
#4:  HOUSE FLY      TRUE
#5:  dragonfly     FALSE
#6: dragon fly     FALSE
...