Drop data frame columns by name

后端 未结 20 2559
花落未央
花落未央 2020-11-22 01:06

I have a number of columns that I would like to remove from a data frame. I know that we can delete them individually using something like:

df$x <- NULL
<         


        
相关标签:
20条回答
  • 2020-11-22 01:52

    Out of interest, this flags up one of R's weird multiple syntax inconsistencies. For example given a two-column data frame:

    df <- data.frame(x=1, y=2)
    

    This gives a data frame

    subset(df, select=-y)
    

    but this gives a vector

    df[,-2]
    

    This is all explained in ?[ but it's not exactly expected behaviour. Well at least not to me...

    0 讨论(0)
  • 2020-11-22 01:53

    If you have a large data.frame and are low on memory use [ . . . . or rm and within to remove columns of a data.frame, as subset is currently (R 3.6.2) using more memory - beside the hint of the manual to use subset interactively.

    getData <- function() {
      n <- 1e7
      set.seed(7)
      data.frame(a = runif(n), b = runif(n), c = runif(n), d = runif(n))
    }
    
    DF <- getData()
    tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
    DF <- DF[setdiff(names(DF), c("a", "c"))] ##
    #DF <- DF[!(names(DF) %in% c("a", "c"))] #Alternative
    #DF <- DF[-match(c("a","c"),names(DF))]  #Alternative
    sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
    #0.1 MB are used
    
    DF <- getData()
    tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
    DF <- subset(DF, select = -c(a, c)) ##
    sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
    #357 MB are used
    
    DF <- getData()
    tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
    DF <- within(DF, rm(a, c)) ##
    sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
    #0.1 MB are used
    
    DF <- getData()
    tt <- sum(.Internal(gc(FALSE, TRUE, TRUE))[13:14])
    DF[c("a", "c")]  <- NULL ##
    sum(.Internal(gc(FALSE, FALSE, TRUE))[13:14]) - tt
    #0.1 MB are used
    
    0 讨论(0)
  • 2020-11-22 01:54

    Provide the data frame and a string of comma separated names to remove:

    remove_features <- function(df, features) {
      rem_vec <- unlist(strsplit(features, ', '))
      res <- df[,!(names(df) %in% rem_vec)]
      return(res)
    }
    

    Usage:

    remove_features(iris, "Sepal.Length, Petal.Width")
    

    0 讨论(0)
  • 2020-11-22 01:55

    There's also the subset command, useful if you know which columns you want:

    df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
    df <- subset(df, select = c(a, c))
    

    UPDATED after comment by @hadley: To drop columns a,c you could do:

    df <- subset(df, select = -c(a, c))
    
    0 讨论(0)
  • 2020-11-22 01:57

    list(NULL) also works:

    dat <- mtcars
    colnames(dat)
    # [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
    # [11] "carb"
    dat[,c("mpg","cyl","wt")] <- list(NULL)
    colnames(dat)
    # [1] "disp" "hp"   "drat" "qsec" "vs"   "am"   "gear" "carb"
    
    0 讨论(0)
  • 2020-11-22 01:57

    Another dplyr answer. If your variables have some common naming structure, you might try starts_with(). For example

    library(dplyr)
    df <- data.frame(var1 = rnorm(5), var2 = rnorm(5), var3 = rnorm (5), 
                     var4 = rnorm(5), char1 = rnorm(5), char2 = rnorm(5))
    df
    #        var2      char1        var4       var3       char2       var1
    #1 -0.4629512 -0.3595079 -0.04763169  0.6398194  0.70996579 0.75879754
    #2  0.5489027  0.1572841 -1.65313658 -1.3228020 -1.42785427 0.31168919
    #3 -0.1707694 -0.9036500  0.47583030 -0.6636173  0.02116066 0.03983268
    df1 <- df %>% select(-starts_with("char"))
    df1
    #        var2        var4       var3       var1
    #1 -0.4629512 -0.04763169  0.6398194 0.75879754
    #2  0.5489027 -1.65313658 -1.3228020 0.31168919
    #3 -0.1707694  0.47583030 -0.6636173 0.03983268
    

    If you want to drop a sequence of variables in the data frame, you can use :. For example if you wanted to drop var2, var3, and all variables in between, you'd just be left with var1:

    df2 <- df1 %>% select(-c(var2:var3) )  
    df2
    #        var1
    #1 0.75879754
    #2 0.31168919
    #3 0.03983268
    
    0 讨论(0)
提交回复
热议问题