Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexing / identifying columns adjacent to a column of interest in R dataframe

Tags:

r

I'm looking for a way to select data/columns adjacent to a particular column. For example, let's say I want to select the two columns to the left and to the right of 'cat_weight'

df <- data.frame(dog_height = 1:5,
                 dog_weight = 2:6,
                 cat_height = 3:7,
                 cat_weight = 4:8,
                 bird_height = 5:9,
                 bird_weight = 6:10
)

So in this case, that would be 'dog_weight', 'cat_height', 'bird_height', and 'bird_weight'. So far what I've tried is simply creating variables to use as index values based on the index number of the column I'm interested in, e.g.

IDvar <- which(colnames(df)=="cat_weight")
IDvar_left_1 <- IDvar-2
IDvar_left_2 <- IDvar-1
IDvar_right_1 <- IDvar+1
IDvar_right_2 <- IDvar+2

cols_left <- df[,IDvar_left_1:IDvar_left_2]
cols_right <- df[,IDvar_right_1:IDvar_right_2]

This works but I can't help but think there must be a more elegant solution?

My real data is, of course, much larger and hence would require some more complex indexing (e.g. excluding columns immediately adjacent to the column of interest), so just trying to work out a simple method to apply!

like image 591
bdog Avatar asked Oct 16 '25 10:10

bdog


1 Answers

You had a good idea, here's a solution using dplyr:

library(dplyr)

df <- data.frame(dog_height = 1:5,
                 dog_weight = 2:6,
                 cat_height = 3:7,
                 cat_weight = 4:8,
                 bird_height = 5:9,
                 bird_weight = 6:10
)


get_range <- function(central_column,
                      max_range){
  range <- seq(which(colnames(df)==central_column)[[1]]-max_range,
               which(colnames(df)==central_column)[[1]]+max_range)
  
  range[! range %in% which(colnames(df)==central_column)]
}



df |> 
  select(all_of(get_range("cat_weight",2))) 

Output:

  dog_weight cat_height bird_height bird_weight
1          2          3           5           6
2          3          4           6           7
3          4          5           7           8
4          5          6           8           9
5          6          7           9          10
like image 113
MonJeanJean Avatar answered Oct 18 '25 23:10

MonJeanJean