我想从数据帧中删除一些列。我知道我们可以使用如下方法单独删除它们:
df$x <- NULL
但我希望用更少的命令来做到这一点。
另外,我知道我可以像这样使用整数索引删除列:
df <- df[ -c(1, 3:6, 12) ]
但我担心变量的相对位置可能会改变。
考虑到R的强大功能,我认为可能有一种比逐个删除每一列更好的方法。
我想从数据帧中删除一些列。我知道我们可以使用如下方法单独删除它们:
df$x <- NULL
但我希望用更少的命令来做到这一点。
另外,我知道我可以像这样使用整数索引删除列:
df <- df[ -c(1, 3:6, 12) ]
但我担心变量的相对位置可能会改变。
考虑到R的强大功能,我认为可能有一种比逐个删除每一列更好的方法。
当前回答
如果你不想使用@hadley's上面的另一个解决方案:如果"COLUMN_NAME"是你想删除的列的名称:
df[,-which(names(df) == "COLUMN_NAME")]
其他回答
你可以使用一个简单的名字列表:
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列值的向量。
使用which找到要删除的列的索引。给这些下标一个负号(*-1)。然后对这些值进行子集化,这将从数据框架中删除它们。这是一个例子。
DF <- data.frame(one=c('a','b'), two=c('c', 'd'), three=c('e', 'f'), four=c('g', 'h'))
DF
# one two three four
#1 a d f i
#2 b e g j
DF[which(names(DF) %in% c('two','three')) *-1]
# one four
#1 a g
#2 b h
在Bernd Bischl的BBmisc包中有一个名为dropNamed()的函数就是这样做的。
BBmisc::dropNamed(df, "x")
优点是它避免了重复数据帧参数,因此适合在magrittr中管道(就像dplyr方法一样):
df %>% BBmisc::dropNamed("x")
如果你有一个大的data.frame和低内存使用[. . . .或rm和within删除data.frame的列,因为子集目前(R 3.6.2)使用更多的内存-除了手册提示交互式使用子集。
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
你可以像这样在%中使用%:
df[, !(colnames(df) %in% c("x","bar","foo"))]