0

Given a dataframe, I want to get column indexes (1,4,55,33..) of columns of type integer.

Given df:

col1           col2
<character>    <integer>
a              1 
a              2  
vb             3

I want to get col1 as character column.

I am trying to do this using:

which(sapply(df, function(x) class(x) == "character") == TRUE)

Please advise.

SteveS
  • 3,789
  • 5
  • 30
  • 64
  • 3
    This should do it, `which(sapply(df, class) == 'integer')` – Sotos Feb 25 '19 at 15:14
  • 4
    The `== TRUE` is not needed since the inner "==" already created a logical vector. I suspect the `which` is not needed either, but unless you show your use case we cannot know for sure, Almost any function that accepts numeric arguments for column selection will also accept a logical vector. There is a probability approaching unity that this question has been asked multiple times in the past on SO. – IRTFM Feb 25 '19 at 15:14
  • 1
    You could also do stuff like `grep("ch", sapply(df, class))` or `grep("in", sapply(df, class))` if you are lazy – David Arenburg Feb 25 '19 at 15:23
  • Possible duplicate of [Determine the data types of a data frame's columns](https://stackoverflow.com/questions/21125222/determine-the-data-types-of-a-data-frames-columns) – divibisan Feb 25 '19 at 18:29
  • 1
    ^ It's not an exact duplicate, since they aren't asking for the index, but once you have a list it's just `which(classes == 'integer')` – divibisan Feb 25 '19 at 18:35
  • 1
    Or maybe cleaner `which(sapply(df, inherits, 'integer'))`. – Rui Barradas Feb 25 '19 at 20:12

2 Answers2

2

You can try:

which(sapply(df, function(x) is.numeric(x)))

col2 
   2 

which(sapply(df, function(x) is.character(x)))

col1 
   1

Or as @David Arenburg suggested:

which(sapply(df, is.character))

col1 
   1 

Sample data:

df <- read.table(text = "col1           col2
 a              1 
a              2  
vb             3", header = TRUE, stringsAsFactors = FALSE)
tmfmnk
  • 38,881
  • 4
  • 47
  • 67
1

We can also use match. The second part of this answer is admittedly overly complicating things.

Purely base R:

 match(names(Filter(is.numeric,df)),names(df))#speed limitations
 #[1] 2

Using Packages:

library(dplyr)
    df1<-df %>% 
      purrr::select_if(is.numeric)

     match(names(df1),names(df))
    #[1] 2

Data:

df <- read.table(text = "col1           col2
 a              1 
a              2  
vb             3", header = TRUE, stringsAsFactors = FALSE)
NelsonGon
  • 13,015
  • 7
  • 27
  • 57
  • Correct me if I am wrong, Filter(is.numeric, df) checks which column in df is numeric and returns logical vector? This vector is the input for the names functions. – SteveS Feb 26 '19 at 08:18
  • `Filter(is.numeric,df)` gets all numeric columns. We then get the names of those columns and `match` them to the original names. – NelsonGon Feb 26 '19 at 10:41