基于 R 中的名称向量删除列



我有一个名为DATAdata.frame。使用BASE R,我想知道如何删除DATA中命名为以下任何变量的任何变量:ar = c("out", "Name", "mdif" , "stder" , "mpre")

目前,我使用DATA[ , !names(DATA) %in% ar]但是虽然这删除了不需要的变量,但它再次创建了一些后缀为.1的新麻烦变量。

提取后,是否可以只删除后缀?

注意1:我们无权访问r,唯一的输入是DATA

注2:这是玩具数据,感谢功能解决方案。

r <- list(
data.frame(Name = rep("Jacob", 6), 
X = c(2,2,1,1,NA, NA), 
Y = c(1,1,1,2,1,NA), 
Z = rep(3, 6), 
out = rep(1, 6)), 
data.frame(Name = rep("Jon", 6), 
X = c(1,NA,3,1,NA,NA), 
Y = c(1,1,1,2,NA,NA), 
Z = rep(2, 6), 
out = rep(1, 6)))
DATA <- do.call(cbind, r)  ## DATA
ar = c("out", "Name", "mdif" , "stder" , "mpre") # The names for exclusion
DATA[ , !names(DATA) %in% ar]      ## Current solution
#>
#    X  Y Z X.1 Y.1 Z.1          ## X.1 Y.1 Z.1  are automatically created but no needed
# 1  2  1 3   1   1   2
# 2  2  1 3  NA   1   2
# 3  1  1 3   3   1   2
# 4  1  2 3   1   2   2
# 5 NA  1 3  NA  NA   2
# 6 NA NA 3  NA  NA   2

理想情况下,列名应该是唯一的,但如果你想保留重复的列名,我们可以在提取后使用sub删除suffixes

DATA1 <- DATA[ , !names(DATA) %in% ar] 
names(DATA1) <- sub("\.\d+", "", names(DATA1))
DATA1
#   X  Y Z  X  Y Z
#1  2  1 3  1  1 2
#2  2  1 3 NA  1 2
#3  1  1 3  3  1 2
#4  1  2 3  1  2 2
#5 NA  1 3 NA NA 2
#6 NA NA 3 NA NA 2

> 在base R中,如果我们创建一个带有索引的对象,我们可以稍后重用它,而不是对列名进行额外的操作

i1 <- !names(DATA) %in% ar
DATA1 <- setNames(DATA[i1], names(DATA)[i1])
DATA1
#   X  Y Z  X  Y Z
#1  2  1 3  1  1 2
#2  2  1 3 NA  1 2
#3  1  1 3  3  1 2
#4  1  2 3  1  2 2
#5 NA  1 3 NA NA 2
#6 NA NA 3 NA NA 2

对于可重用性,我们可以创建一个函数

f1 <- function(dat, vec) {
i1 <- !names(dat) %in% vec
setNames(dat[i1], names(dat)[i1])
}
f1(DATA, ar)

如果数据集存储在list中,请使用lapply遍历list并应用f1

lst1 <- list(DATA, DATA)
lapply(lst1, f1, vec = ar)

如果不同list元素的"ar"元素也不同

arLst <- list(ar1, ar2)
Map(f1, lst1, vec = arLst)

这里

ar1 <- c("out", "Name")
ar2 <- c("mdif" , "stder" , "mpre")

这也是使用tidyverse的另一个选项

library(dplyr)
library(stringr)
DATA %>% 
set_names(make.unique(names(.))) %>% 
select(-matches(str_c(ar, collapse="|"))) %>%
set_names(str_remove(names(.), "\.\d+$"))
#   X  Y Z  X  Y Z
#1  2  1 3  1  1 2
#2  2  1 3 NA  1 2
#3  1  1 3  3  1 2
#4  1  2 3  1  2 2
#5 NA  1 3 NA NA 2
#6 NA NA 3 NA NA 2

注意:不建议使用重复的列名

最新更新