根据矢量中的* not *选择R数据帧中的列

时间:2012-08-31 02:16:05

标签: r dataframe subset

我很熟悉能够从R数据框(或矩阵)中提取列,如下所示:

df.2 <- df[, c("name1", "name2", "name3")]

但是,可以使用!或其他工具来选择除了列出的列以外的所有吗?

对于背景,我有一个包含很多列向量的数据框,我想避免:

  • 当我可以删除少数人时,键入大部分名称
  • 使用更短的df.2 <- df[, c(1,3,5)],因为当我的.csv文件发生变化时,我的代码就变成了问题,因为编号不再相同了。我是R的新手,并认为我已经学会了很难不使用数字向量来更大的df可能会改变。

我试过了:

df.2 <- df[, !c("name1", "name2", "name3")]
df.2 <- df[, !=c("name1", "name2", "name3")]

正如我输入的那样,发现这有效:

df.2 <- df[, !names(df) %in% c("name1", "name2", "name3")]

有没有比上一个更好的方法?

6 个答案:

答案 0 :(得分:27)

grep的替代方案是which

df.2 <- df[, -which(names(df) %in% c("name1", "name2", "name3"))]

答案 1 :(得分:11)

您可以使用negative-grep进行更短的调用:

df.2 <- df[, -grep("^name[1:3]$", names(df) )] 

由于grep返回数字,您可以使用负向量索引来删除列。您可以添加更多数量或更复杂的模式。

答案 2 :(得分:6)

dplyr::select()有几种删除特定列的选项:

library(dplyr)

drop_columns <- c('cyl','disp','hp')
mtcars %>% 
  select(-one_of(drop_columns)) %>% 
  head(2)

              mpg drat    wt  qsec vs am gear carb
Mazda RX4      21  3.9 2.620 16.46  0  1    4    4
Mazda RX4 Wag  21  3.9 2.875 17.02  0  1    4    4

取消特定列名称,以下内容将删除列&#34; hp&#34;来自&#34; qsec&#34;的列通过&#34;齿轮&#34;:

mtcars %>% 
  select(-hp, -(qsec:gear)) %>% 
  head(2)

              mpg cyl disp drat    wt carb
Mazda RX4      21   6  160  3.9 2.620    4
Mazda RX4 Wag  21   6  160  3.9 2.875    4

您还可以否定contains()starts_with()ends_with()matches()

mtcars %>% 
  select(-contains('t')) %>%
  select(-starts_with('a')) %>% 
  select(-ends_with('b')) %>% 
  select(-matches('^m.+g$')) %>% 
  head(2)

              cyl disp  hp  qsec vs gear
Mazda RX4       6  160 110 16.46  0    4
Mazda RX4 Wag   6  160 110 17.02  0    4

答案 3 :(得分:2)

如果您使用自定义函数来操作数据,则可以创建自定义函数。我可能会这样做:

rm.col <- function(df, ...) {
    x <- substitute(...())
    z <- Trim(unlist(lapply(x, function(y) as.character(y))))
    df[, !names(df) %in% z]
}

rm.col(mtcars, hp, mpg)

第一个参数是数据框名称。以下...是您要删除的任何列的名称。

答案 4 :(得分:2)

旧线程,但这是另一种解决方案:

df.2 <- subset(df, select=-c(name1, name2, name3))

这是在另一个类似的帖子中发布的(虽然我现在无法找到它)。在您描述的情况下应该是可持续的代码,并且可能比其他一些选项更容易阅读和编辑。

答案 5 :(得分:0)

我想到的最简单的方法:

  

filtered_df&lt; -df [,setdiff(names(df),c(&#34; name1&#34;,&#34; name2&#34;)]

基本上,您正在计算列名称的完整列表与要过滤的子集之间的集合差异(上面的name1和name2)。