Reputation: 1939
Here's a sample data frame.
df = data.frame(company = c('a', 'b', 'c', 'd'),
bond = c(0.2, 1, 0.3, 0),
equity = c(0.7, 0, 0.5, 1),
cash = c(0.1, 0, 0.2, 0))
df
company bond equity cash
1 a 0.2 0.7 0.1
2 b 1.0 0.0 0.0
3 c 0.3 0.5 0.2
4 d 0.0 1.0 0.0
I need to find companies which have 1.0 in any columns. The expected result should be b and d.
Please provide a solution that works for >20 columns.
Solutions like df %>% filter(bond == 1)
only works for searching a particular column.
dplyr
or data.table
solutions are acceptable.
Thanks.
Upvotes: 5
Views: 5228
Reputation: 887048
We can also use Reduce
with ==
res <- df[Reduce(`+`, lapply(df[-1], `==`, 1))!=0,]
res
# company bond equity cash
#2 b 1 0 0
#4 d 0 1 0
res$company
#[1] b d
#Levels: a b c d
Upvotes: 5
Reputation: 93813
Another option:
df[unique(row(df[-1])[df[-1] == 1L]),]
# company bond equity cash
#2 b 1 0 0
#4 d 0 1 0
df$company[unique(row(df[-1])[df[-1] == 1L])]
#[1] b d
#Levels: a b c d
Upvotes: 4
Reputation: 7153
var <- df %>% select(bond:cash) %>% names
plyr::ldply(var, function(x) paste("filter(df,", x, "==1)") %>% parse(text=.) %>% eval)
company bond equity cash
1 b 1 0 0
2 d 0 1 0
Upvotes: 2
Reputation: 214927
Use rowSums
to check the logic data frame should work:
df[rowSums(df[-1] == 1.0) != 0, 'company']
[1] b d
Levels: a b c d
Upvotes: 4