проверка состояния - разреженные данные - PullRequest
0 голосов
/ 18 марта 2019

Я хотел проверить условие: если col = = 'value', то если из списка столбцов есть какой-либо столбец == 'value2'

# create dummy data set
pb=c('1','0','0','0','0','1','Not_ans','1','0','Not_ans')
qa=c('1','1','0','0','1','0','Not_ans','1','Not_ans','Not_ans')
#zy=c('1','Not_ans','0','1','Not_ans','0','1','1','1','Not_ans')

#sub questions for pb
pb.abr=c('1','0','0','0','0','1','0','1','0','0')
pb.ras=c('0','0','0','0','1','0','0','1','0','0')
pb.sfg=c('1','0','0','0','0','0','0','1','0','0')

#sub questions for qa
qa.fgs=c('1','0','0','0','0','0','0','1','0','0')
qa.sdf=c('0','1','0','0','0','0','0','0','0','0')
qa.tyu=c('0','0','0','0','1','0','0','1','0','0')

df=data.frame(pb,qa,pb.abr,pb.ras,pb.sfg,qa.fgs,qa.sdf,qa.tyu)
df

        pb      qa     pb.abr pb.ras pb.sfg qa.fgs qa.sdf qa.tyu
1        1       1      1      0      1      1      0      0
2        0       1      0      0      0      0      1      0
3        0       0      0      0      0      0      0      0
4        0       0      0      0      0      0      0      0
5        0       1      0      1      0      0      0      1
6        1       0      1      0      0      0      0      0
7  Not_ans Not_ans      0      0      0      0      0      0
8        1       1      1      1      1      1      0      1
9        0 Not_ans      0      0      0      0      0      0
10 Not_ans Not_ans      0      0      0      0      0      0

в указанном выше наборе данных - я хочу проверить, равен ли столбец 'pb' 0, а затем столбцам pb.abr ИЛИ pb.ras ИЛИ pb.sfg == 1

subset_df=subset(df,(pb==0) & ((pb.abr==1) | (pb.ras==1)|(pb.sfg==1)))

Проблема в том, что у меня есть сотни столбцов, которые имеют формат pb.xxx, и ручная запись всех столбцов в подмножестве не является возможным решением. Как проверить вышеизложенное с помощью логики, которая использует contains("pb."), и проверить по столбцам с условием OR между столбцами и, в конце концов, предоставить фрейм данных?

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

Мы могли бы использовать filter_at

library(dplyr)

df %>%
  filter(pb == 0) %>%
  filter_at(vars(matches("pb\\.")), any_vars(.  == 1))

#  pb qa pb.abr pb.ras pb.sfg qa.fgs qa.sdf qa.tyu
#1  0  1      0      1      0      0      0      1

или в базе R

df[df$pb == 0 & rowSums(df[grep("pb\\.", names(df))] == 1) > 0, ]

#  pb qa pb.abr pb.ras pb.sfg qa.fgs qa.sdf qa.tyu
#5  0  1      0      1      0      0      0      1
0 голосов
/ 18 марта 2019

Как один вкладыш:

filter(df,pb==0 & rowSums(z[,grepl("pb\\.",names(z))])>0)
0 голосов
/ 18 марта 2019

пример данных

dont' forget to set StringsAsFactors to FALSE!
df=data.frame(pb,qa,pb.abr,pb.ras,pb.sfg,qa.fgs,qa.sdf,qa.tyu, stringsAsFactors = FALSE)

код

library(dplyr)
df %>%
  #set all columns starting with 'pb.' to numeric
  mutate_at( vars( starts_with("pb.") ), funs( as.numeric ) ) %>%
  #first filter
  filter( pb == "0" ) %>%
  #second filter
  filter( rowSums( .[, grep("pb\\.", names(df))]) > 0 ) 

выход

  pb qa pb.abr pb.ras pb.sfg qa.fgs qa.sdf qa.tyu
1  0  1      0      1      0      0      0      1
...