How to extract column index of a dataframe with the variable name?

Viewed 226

I would like to extract the column index of a variable of a dataframe using the variable name.

here is the df for exemple:

>df 

  Mean  Var  Max
a  1     0.5  3
b  1.5   0.4  4
c  0.7   0.3  2.5
d  0.3   0.1  0.5

I want to "reverse" this:

> variable.names(df[2])
[1] "Var"

with something like that:

> variable.names(df$Var)
NULL

But getting "2" instead of "NULL"

here is my entire problem:

my_fct ← function(data, v_cont, v_cat){  
  for (i in 1:nlevels(as.factor(v_cat))){      
      sub <- subset(data , v_cat == levels(as.factor(v_cat))[i])     
      sub_stat <- c(levels(as.factor(v_cat))[i],                    
                    mean( **sub[,COLINDEX(v_cat)**] , na.rm = TRUE)     
      mat_stat <- rbind(mat_stat, sub_stat)

sub[,COLINDEX(v_cat) is what need to solve. How to select the initial variable in my new matrix freshly created?

Note: v_cat and v_cont have the following form: df$variable1 , df$variable2

thanks for helping

4 Answers

Similar to LMc(+1) solution -> We could use grep:

df <- structure(list(Mean = c(1, 1.5, 0.7, 0.3), Var = c(0.5, 0.4, 
0.3, 0.1), Max = c(3, 4, 2.5, 0.5)), class = "data.frame", row.names = c("a", 
"b", "c", "d"))

grep("Var", colnames(df))

output:

[1] 2

It is not entirely clear about the situation. But based on the function provided, it can rewritten by passing the column name and subsetting with [[ instead of passing the df$variable1 or df$variable2

my_fct <- function(data, v_cont, v_cat){  
  mat_stat <- NULL
  for (i in 1:nlevels(as.factor(data[[v_cat]]))){      
      sub <- subset(data , data[[v_cat]] == 
              levels(as.factor(data[[v_cat]]))[i])     
      sub_stat <- c(levels(as.factor(data[[v_cat]]))[i],                    
                    mean(sub[,v_cat] , na.rm = TRUE)  
       mat_stat <- rbind(mat_stat, sub_stat)
                    
    }
    return(mat_stat)
}

-testing

my_fct(df, "variable1", "variable2")

With the OP's original function if the input is df$variable1, df$variable2, an option is to use deparse(subsitute to capture the argument, extract the column name with sub and use that as column name

my_fct <- function(data, v_cont, v_cat){ 
  nm1 <- sub(".*\\$", "", deparse(substitute(v_cat)))
  mat_stat <- NULL
  for (i in 1:nlevels(as.factor(v_cat))){      
      sub <- subset(data , v_cat == levels(as.factor(v_cat))[i])     
      sub_stat <- c(levels(as.factor(v_cat))[i],                    
                    mean(sub[, nm1] , na.rm = TRUE)     
      mat_stat <- rbind(mat_stat, sub_stat)
      }
      
      return(mat_stat)
      
}

-testing

my_fct(df, df$variable1, df$variable2)

Use match:

match("Var", colnames(df))

This should do it using which

df <- data.frame(Mean=c(1,1.5,0.7,0.3),Var=c(0.5,0.4,0.3,0.1),Max=c(3,4,2.5,0.5))
df

  Mean Var Max
1  1.0 0.5 3.0
2  1.5 0.4 4.0
3  0.7 0.3 2.5
4  0.3 0.1 0.5


which(colnames(df)=="Var")

Output:

[1] 2
Related