opposity
opposity

Reputation: 111

Find all column names where any specified row will have the cell value of 1

Here is a question I have regarding my project.

Let's say that I have this dataset.

  X1 X2 X3 X4
1  1  2  1  3
2  1  3  2  1
3  1  3  4  2
4  1  1  2  3
5  3  4  3  2
6  2  1  3  4

From this dataset, I would like to be able to specify any random row and find out the column names where the cell is equal to 1. For example, if I were to specify the 1st row, then I would get X1 and X3 as my output. Likewise, if I were to specify the 2nd row, then I would get X1 and X4 as my output. If I were to specify the 3rd row, then I would get X1 as my output.

I hope these examples make sense. I have looked around on StackOverflow but I was not able to find what I was looking for. I would really appreciate it if you could help me with this problem.

Upvotes: 3

Views: 785

Answers (4)

GKi
GKi

Reputation: 39657

You can use names and subset it where the condition == 1 is the case for the subseted row using [row,] on the data:

names(x)[x[1,] == 1]  #For 1st row
#[1] "X1" "X3"

names(x)[x[2,] == 1]  #For 2nd row
#[1] "X1" "X4"

Data:

x <- data.frame(X1 = c(1, 1, 1, 1, 3, 2), X2 = c(2, 3, 3, 1, 4, 1)
              , X3 = c(1, 2, 4, 2, 3, 3), X4 = c(3, 1, 2, 3, 2, 4))

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388982

Here's a dplyr way -

library(dplyr)

return_cols <- function(df, i) {
  df %>%
    slice(i) %>%
    select(where(~. == 1)) %>%
    names
}

df %>% return_cols(1)
#[1] "X1" "X3"

df %>% return_cols(2)
#[1] "X1" "X4"

Upvotes: 1

ThomasIsCoding
ThomasIsCoding

Reputation: 101343

We can define a custom function f using which + subset like below

f <- function(df, r) names(df)[subset(data.frame(which(df == 1, arr.ind = TRUE)), row == r)$col]

and you will see

> f(df, 1)
[1] "X1" "X3"

> f(df, 2)
[1] "X1" "X4"

Upvotes: 1

akrun
akrun

Reputation: 887118

We can create a function with arguments, data and the index to pass, subset the data, create a logical vector and return the names of the dataset

 f1 <- function(dat, i) {
           tmp <- dat[i, ]
           names(tmp)[tmp == 1]
   }

-testing

> f1(df1, 1)
[1] "X1" "X3"

data

df1 <- structure(list(X1 = c(1L, 1L, 1L, 1L, 3L, 2L), X2 = c(2L, 3L, 
3L, 1L, 4L, 1L), X3 = c(1L, 2L, 4L, 2L, 3L, 3L), X4 = c(3L, 1L, 
2L, 3L, 2L, 4L)), class = "data.frame", row.names = c("1", "2", 
"3", "4", "5", "6"))

Upvotes: 4

Related Questions