shawnl
shawnl

Reputation: 1939

Search values across all columns in R data frame

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

Answers (4)

akrun
akrun

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

thelatemail
thelatemail

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

Adam Quek
Adam Quek

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

akuiper
akuiper

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

Related Questions