16

Why doesn't this work with data.table?

It works with data.frame. Is there a way to do this with a data table?

x <- data.table(v1=1:20,v2=1:20,v3=1:20,v4=letters[1:20])
y <- x[ , sapply(x, is.numeric)]

This returns:

v1    v2    v3    v4
TRUE  TRUE  TRUE FALSE
3

5 Answers 5

44

From data.table 1.13.0 ".SDcols accepts a function which is used to select the columns of .SD". Thus, simply .SDcols = is.numeric:

x[ , .SD, .SDcols = is.numeric]
Sign up to request clarification or add additional context in comments.

2 Comments

Hello Hello, I tried. dt_c[,.SD, .SDcols = sapply(dt_c, as.character)] It's not working. a solution
s/as.character/is.character/.
15

data.table needs the with=FALSE to grab column numbers.

tokeep <- which(sapply(x,is.numeric))
x[ , tokeep, with=FALSE]

1 Comment

Is the which even needed? - x[,sapply(x,is.numeric),with=FALSE]
3

You may also try:

 x1 <- x[,Filter(is.numeric, .SD)]
 head(x1,3)
 #   v1 v2 v3
#1:  1  1  1
#2:  2  2  2
#3:  3  3  3

Although, I have to admit that it is slow for bigger datasets.

Comments

0

Similar to @akrun's answer

Filter(is.numeric, x)

Comments

0

We can write a custom helper calledwhere(), and then we can subset a data.frame/data.table where f is satisfied:

where <- function(x, f) {
  colnames(x)[vapply(x, f, logical(1))]
}

df[, where(df, is.numeric), with = FALSE]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.