99

What is an easy way to find out what class each column is in a data frame?

AndrewGB
  • 16,126
  • 5
  • 18
  • 49
Kyle Brandt
  • 26,938
  • 37
  • 124
  • 165

5 Answers5

106

One option is to use lapply and class. For example:

> foo <- data.frame(c("a", "b"), c(1, 2))
> names(foo) <- c("SomeFactor", "SomeNumeric")
> lapply(foo, class)
$SomeFactor
[1] "factor"

$SomeNumeric
[1] "numeric"

Another option is str:

> str(foo)
'data.frame':   2 obs. of  2 variables:
 $ SomeFactor : Factor w/ 2 levels "a","b": 1 2
 $ SomeNumeric: num  1 2
Kyle Brandt
  • 26,938
  • 37
  • 124
  • 165
  • 11
    Since `class` returns a character vector of _all_ classes an object inherits from, the output of `sapply(foo, class)` might be a list, and not always a character vector as most people would expect. Which can be a bit dangerous... I find `lapply` a lot safer. – flodel May 19 '12 at 13:53
  • 1
    for better readability I suggest: ```unlist(lapply(foo, class))``` which is handy with data frames with a lot of columns. – p130ter Jan 12 '18 at 09:58
  • 2
    `unlist` with `lapply` is a terrible idea because it is possible that `length(class(x))>1` (see comments above) -- `sapply` is a lot safer than `unlist + lapply`. a safe way would be `sapply(lapply(foo, class), "[", 1)` - given that foo is a data frame – lebatsnok Oct 17 '18 at 10:16
  • One could also use `do.call(c, lapply(foo, class))` to obtain a vector of classes. – Dion Groothof Mar 02 '22 at 22:48
33

You can simple make use of lapply or sapply builtin functions.

lapply will return you a list -

lapply(dataframe,class)

while sapply will take the best possible return type ex. Vector etc -

sapply(dataframe,class)

Both the commands will return you all the column names with their respective class.

Stephan
  • 2,056
  • 1
  • 9
  • 20
Rohit Saini
  • 487
  • 4
  • 8
3

Hello was looking for the same, and it could be also

unlist(lapply(mtcars,class))
Seyma Kalay
  • 2,037
  • 10
  • 22
3

I wanted a more compact output than the great answers above using lapply, so here's an alternative wrapped as a small function.

# Example data
df <-
    data.frame(
        w = seq.int(10),
        x = LETTERS[seq.int(10)],
        y = factor(letters[seq.int(10)]),
        z = seq(
            as.POSIXct('2020-01-01'),
            as.POSIXct('2020-10-01'),
            length.out = 10
        )
    )

# Function returning compact column classes
col_classes <- function(df) {
    t(as.data.frame(lapply(df, function(x) paste(class(x), collapse = ','))))
}

# Return example data's column classes
col_classes(df)
  [,1]            
w "integer"       
x "character"     
y "factor"        
z "POSIXct,POSIXt"
Alec
  • 63
  • 1
  • 3
  • Are you sure you want your result to be a 1-column matrix? Why? How about a character vector instead? – nbenn Dec 04 '20 at 18:08
  • Sure, why not return a 1-column matrix? I stated this solution is for a compact output, useful for returning to check after manipulating a data.frame for example. It isn't meant to be used for downstream processing of column classes. The other answers above return a character vector. – Alec Dec 07 '20 at 15:44
2

You can use purrr as well, which is similar to apply family functions:

as.data.frame(purrr::map_chr(mtcars, class))
purrr::map_df(mtcars, class)
AlexB
  • 3,061
  • 2
  • 17
  • 19