Как отфильтровать кадр данных с вектором символов - PullRequest
4 голосов
/ 31 октября 2019

Я пытаюсь отфильтровать data.frame с помощью функции filter() из пакета dplyr. Основная проблема здесь в том, что я хочу использовать вектор для условий.

Например,

library(dplyr)
conditions <- c("Sepal.Width<3.2","Species==setosa")
DATA <- iris %>%
  filter(conditions) #This doesnt work, of course.

Есть ли какая-нибудь функция, которая приняла бы

conditions <- c("Sepal.Width<3.2","Species==setosa")

в качествевход и дать мне

Sepal.Width<3.2 & Species==setosa

в качестве выхода? Я думаю об использовании eval(parse...) с sapply и, возможно, paste0() для добавления &, но не могу заставить его работать.

Любая помощь будет признана недействительной.

Ответы [ 3 ]

3 голосов
/ 31 октября 2019

Вот a way:

conditions <- c("Sepal.Width<3.2","Species=='setosa'")
# note the small change here:               ↑      ↑
DATA <- iris %>%
  filter(eval(parse(text = paste(conditions, collapse = "&"))))

> DATA
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           4.9         3.0          1.4         0.2  setosa
2           4.6         3.1          1.5         0.2  setosa
3           4.4         2.9          1.4         0.2  setosa
4           4.9         3.1          1.5         0.1  setosa
5           4.8         3.0          1.4         0.1  setosa
6           4.3         3.0          1.1         0.1  setosa
7           5.0         3.0          1.6         0.2  setosa
8           4.8         3.1          1.6         0.2  setosa
9           4.9         3.1          1.5         0.2  setosa
10          4.4         3.0          1.3         0.2  setosa
11          4.5         2.3          1.3         0.3  setosa
12          4.8         3.0          1.4         0.3  setosa
3 голосов
/ 31 октября 2019

Есть несколько проблем. Сначала вам нужно заключить в кавычку второе условие:

conditions <- c("Sepal.Width < 3.2", "Species == 'setosa'")

Затем необходимо указать связь между этими двумя условиями. Здесь я предположил &. Тогда вы можете использовать eval(parse(...)):

iris %>%
 filter(eval(parse(text = paste(conditions, sep = "&"))))

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           5.1         3.5          1.4         0.2  setosa
2           4.9         3.0          1.4         0.2  setosa
3           4.7         3.2          1.3         0.2  setosa
4           4.6         3.1          1.5         0.2  setosa
5           5.0         3.6          1.4         0.2  setosa
6           5.4         3.9          1.7         0.4  setosa
7           4.6         3.4          1.4         0.3  setosa
8           5.0         3.4          1.5         0.2  setosa
9           4.4         2.9          1.4         0.2  setosa
10          4.9         3.1          1.5         0.1  setosa

С другой стороны, я думаю, что всегда важно цитировать @ Martin Mächler , чтобы предупредить о потенциальных проблемах, связанных с этим подходом:

(возможно) единственное соединение - через синтаксический анализ (text = ....), и все хорошие программисты на R должны знать, что это редко является эффективным или безопасным средством для создания выражений (или вызовов). Скорее узнайте больше о substitute (), quote () и, возможно, о возможности использования do.call (заменитель ......).

2 голосов
/ 31 октября 2019

Tidyeval способ будет использовать rlang::parse_exprs().

library(dplyr)

conditions <- c("Sepal.Width < 3.2", "Species == 'setosa'")

iris %>%
  filter( !!! rlang::parse_exprs(conditions))

   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1           4.9         3.0          1.4         0.2  setosa
2           4.6         3.1          1.5         0.2  setosa
3           4.4         2.9          1.4         0.2  setosa
4           4.9         3.1          1.5         0.1  setosa
5           4.8         3.0          1.4         0.1  setosa
6           4.3         3.0          1.1         0.1  setosa
7           5.0         3.0          1.6         0.2  setosa
8           4.8         3.1          1.6         0.2  setosa
9           4.9         3.1          1.5         0.2  setosa
10          4.4         3.0          1.3         0.2  setosa
11          4.5         2.3          1.3         0.3  setosa
12          4.8         3.0          1.4         0.3  setosa
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...