我很熟悉能够从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")]
有没有比上一个更好的方法?
答案 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)。