Добавить условия динамического подмножества в качестве переменных в data.frame - PullRequest
1 голос
/ 03 апреля 2019

У меня есть фрейм данных, как

> x = data.frame(A=c(1,2,3),B=c(2,3,4))
> x
  A B
1 1 2
2 2 3
3 3 4

и условия поднабора в кадре данных, такие как

> cond = data.frame(condition=c('A>1','B>2 & B<4'))
> cond
  condition
1       A>1
2 B>2 & B<4

который я затем применяю динамически

> eval(parse(text=paste0("subset(x,",cond[1,'condition'],")")))
  A B
2 2 3
3 3 4
> eval(parse(text=paste0("subset(x,",cond[2,'condition'],")")))
  A B
2 2 3

Теперь вместо поднабора я хотел бы добавить условия поднабора в качестве переменных в данные. Конечный результат будет выглядеть как

  A B condition1 condition2
1 1 2          0          0  
2 2 3          1          1
3 3 4          1          0

Как я могу получить приведенную выше таблицу, используя динамические условия?

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Прежде чем использовать eval parse, я надеюсь, что вы прошли через некоторые чтения, такие как

Какие конкретно опасности eval (parse (…))?

и многие другие, которые доступны.

Однако, чтобы ответить на ваш вопрос, мы можем продолжить ваш поток и использовать eval parse в sapply

+(sapply(seq_len(nrow(cond)), function(i) 
            eval(parse(text=paste0("with(x,",cond[i,'condition'],")")))))

#     [,1] [,2]
#[1,]    0    0
#[2,]    1    1
#[3,]    1    0

Чтобы добавить его в кадр данных,

x[paste0("condition", 1:nrow(cond))] <- 
         +(sapply(seq_len(nrow(cond)), function(i) 
         eval(parse(text=paste0("with(x,",cond[i,'condition'],")")))))

x
#  A B condition1 condition2
#1 1 2          0          0
#2 2 3          1          1
#3 3 4          1          0

Немного упростить его (используя комментарий @ jogo)

+(sapply(cond$condition, function(i) with(x, eval(parse(text=as.character(i))))))

#     [,1] [,2]
#[1,]    0    0
#[2,]    1    1
#[3,]    1    0
0 голосов
/ 03 апреля 2019

Здесь можно использовать tidyverse

library(tidyverse)
x %>%   
  mutate(!!! rlang::parse_exprs(str_c(cond$condition, collapse=";"))) %>% 
  rename_at(3:4, ~ paste0("condition", 1:2))
#  A B condition1 condition2
#1 1 2      FALSE      FALSE
#2 2 3       TRUE       TRUE
#3 3 4       TRUE      FALSE

При необходимости столбцы logical можно легко преобразовать в двоичный файл с помощью as.integer

...