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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.