下面的示例代码可以正常工作,但是我的问题是如何用更少的代码和更优雅的方式编写代码?
重点是我有相似名称的列。在此示例中,我想选择所有以B
开头且所有值为FALSE
的列。
set.seed(0)
df <- data.frame(A = sample(c(T, F), 100, replace=T),
B1 = sample(c(T, F), 100, replace=T),
B2 = sample(c(T, F), 100, replace=T),
B3 = sample(c(T, F), 100, replace=T))
n <- names(df)[startsWith(names(df), 'B')]
result <- df[df$B1 == FALSE & df$B2 == FALSE & df$B3 == FALSE, n]
print(result)
结果是
B1 B2 B3
1 FALSE FALSE FALSE
26 FALSE FALSE FALSE
31 FALSE FALSE FALSE
35 FALSE FALSE FALSE
51 FALSE FALSE FALSE
66 FALSE FALSE FALSE
70 FALSE FALSE FALSE
84 FALSE FALSE FALSE
我尝试过的结果出乎意料
df[df[,n] == FALSE, n]
答案 0 :(得分:3)
在基数R中,我们可以选择以“ B”开头的列,然后使用rowSums
选择总和等于0的行。
inds <- grepl("^B", names(df))
df[rowSums(df[inds]) == 0, inds]
# B1 B2 B3
#1 FALSE FALSE FALSE
#26 FALSE FALSE FALSE
#31 FALSE FALSE FALSE
#35 FALSE FALSE FALSE
#51 FALSE FALSE FALSE
#66 FALSE FALSE FALSE
#70 FALSE FALSE FALSE
#84 FALSE FALSE FALSE
或者就像@snoram提到的那样,我们可以做得更简洁
df[!rowSums(df[inds]), inds]
答案 1 :(得分:1)
使用tidyverse:
df %>% select(matches("^B")) %>% filter_all(all_vars(.==FALSE))
或者,如果您要检查行号:
df %>% mutate(id=row_number()) %>% # copy row number to new variable
select(id,matches("^B")) %>% # keeps id and variables beginning with B
filter_at(vars(matches("^B")), # for variables beginning with B
all_vars(.==FALSE)) # keep rows where all are FALSE
# id B1 B2 B3
#1 1 FALSE FALSE FALSE
#2 26 FALSE FALSE FALSE
#3 31 FALSE FALSE FALSE
#4 35 FALSE FALSE FALSE
#5 51 FALSE FALSE FALSE
#6 66 FALSE FALSE FALSE
#7 70 FALSE FALSE FALSE
#8 84 FALSE FALSE FALSE
答案 2 :(得分:1)
一种快速的base-R替代品:
df[!do.call(pmax, df[n]), n]
B1 B2 B3
1 FALSE FALSE FALSE
26 FALSE FALSE FALSE
31 FALSE FALSE FALSE
35 FALSE FALSE FALSE
51 FALSE FALSE FALSE
66 FALSE FALSE FALSE
70 FALSE FALSE FALSE
84 FALSE FALSE FALSE
编辑
尽量靠近您可以做的原始尝试:
df[apply(df[n] == FALSE, 1, all), n]
# or
df[apply(!df[n], 1, all), n]
答案 3 :(得分:1)
我会这样:
您的数据:
df <- data.frame(A = sample(c(T, F), 100, replace=T),
B1 = sample(c(T, F), 100, replace=T),
B2 = sample(c(T, F), 100, replace=T),
B3 = sample(c(T, F), 100, replace=T))
代码:
df<- as.data.frame(!df[,grepl("^B",names(df))])
!df[apply(df,1,all),]
结果:
# B1 B2 B3
#1 FALSE FALSE FALSE
#26 FALSE FALSE FALSE
#31 FALSE FALSE FALSE
#35 FALSE FALSE FALSE
#51 FALSE FALSE FALSE
#66 FALSE FALSE FALSE
#70 FALSE FALSE FALSE
#84 FALSE FALSE FALSE
答案 4 :(得分:1)
在base R
中,我们可以做到
df[!Reduce(`|`, df[grep("^B", names(df))]),]
# A B1 B2 B3
#1 FALSE FALSE FALSE FALSE
#26 TRUE FALSE FALSE FALSE
#31 TRUE FALSE FALSE FALSE
#35 TRUE FALSE FALSE FALSE
#51 FALSE FALSE FALSE FALSE
#66 FALSE FALSE FALSE FALSE
#70 TRUE FALSE FALSE FALSE
#84 TRUE FALSE FALSE FALSE