按名称删除数据框列

df$x <- NULL
df <- df[ -c(1, 3:6, 12) ]

答案

您可以使用简单的名称列表:

DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
drops <- c("x","z")
DF[ , !(names(DF) %in% drops)]

或者,您也可以列出要保留的内容,并按名称引用它们:

keeps <- c("y", "a")
DF[keeps]

编辑:对于那些仍不熟悉索引函数的drop参数的用户,如果要保留一列作为数据框,请执行以下操作:

keeps <- "y"
DF[ , keeps, drop = FALSE]

drop=TRUE (或不提及它)将删除不必要的尺寸,因此返回带有y列值的向量。

还有subset命令,如果您知道需要哪些列,则很有用:

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

@hadley 发表评论后更新:要删除 a,c 列,您可以执行以下操作:

df <- subset(df, select = -c(a, c))
within(df, rm(x))

是最简单的,或者对于多个变量:

within(df, rm(x, y))

或者,如果您正在处理data.table (请data.table 如何在 data.table 中按名称删除列? ):

dt[, x := NULL]   # Deletes column x by reference instantly.

dt[, !"x"]   # Selects all but x into a new data.table.

或多个变量

dt[, c("x","y") := NULL]

dt[, !c("x", "y")]

您可以这样使用%in%

df[, !(colnames(df) %in% c("x","bar","foo"))]

list(NULL)也可以:

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"

根据 grep()将返回数字矢量这一事实,有一种可能更强大的策略。如果您像我在一个数据集中那样拥有一长串变量,那么某些变量以 “.A” 结尾,而另一些变量以 “.B” 结尾,而您只希望那些以 “.A” 结尾的变量(以及对于所有与任一模式都不匹配的变量,请执行以下操作:

dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]

对于当前情况,以 Joris Meys 为例,它可能不那么紧凑,但可能是:

DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]

如果要通过引用删除列并避免与data.frames相关的内部复制,则可以使用data.table包和函数:=

您可以将字符向量名称传递给:=运算符的左侧,而将NULL作为 RHS 传递。

library(data.table)

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# or more simply  DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10) #

DT[, c('a','b') := NULL]

如果要将名称预先定义为对[的调用之外的字符向量,请在(){}包装对象的名称,以强制在调用范围内评估 LHS 而不是在DT范围内的名称。

del <- c('a','b')
DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, (del) := NULL]
DT <-  <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, {del} := NULL]
# force or `c` would also work.

您还可以使用set ,它避免了[.data.table的开销, 并且也适用于data.frames

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)

# drop `a` from df (no copying involved)

set(df, j = 'a', value = NULL)
# drop `b` from DT (no copying involved)
set(DT, j = 'b', value = NULL)

另一个dplyr答案。如果您的变量具有某些通用的命名结构,则可以尝试starts_with() 。例如

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

如果要在数据框中删除一系列变量,则可以使用: 。例如,如果您要删除var2var3以及之间的所有变量, var3剩下var1

df2 <- df1 %>% select(-c(var2:var3) )  
df2
#        var1
#1 0.75879754
#2 0.31168919
#3 0.03983268
DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
DF

输出:

x  y z  a
1   1 10 5 11
2   2  9 5 12
3   3  8 5 13
4   4  7 5 14
5   5  6 5 15
6   6  5 5 16
7   7  4 5 17
8   8  3 5 18
9   9  2 5 19
10 10  1 5 20

DF[c("a","x")] <- list(NULL)

输出:

y z
    1  10 5
    2   9 5
    3   8 5
    4   7 5
    5   6 5
    6   5 5
    7   4 5
    8   3 5    
    9   2 5
    10  1 5

Dplyr 解决方案

我怀疑这会在这里引起很多关注,但是如果您有要删除的列列表,并且想在dplyr链中进行操作,则可以在select子句中使用one_of()

这是一个简单的可复制示例:

undesired <- c('mpg', 'cyl', 'hp')

mtcars <- mtcars %>%
  select(-one_of(undesired))

可以通过运行?one_of或在此处找到文档:

http://genomicsclass.github.io/book/pages/dplyr_tutorial.html