如何使用R根据外部列表从数据框中删除行?

35

这可能是一个简单的问题,但我仍然需要一些关于使用R的帮助。

我有一个数据框(main_data),比如说...

NAMES   AGE     LOC
Jyo     23      Hyd
Abid    27      Kar
Ras     24      Pun
Poo     25      Goa
Sus     28      Kar

我希望根据一组名称从表格中删除几行。假设我有另一个表格的列表如下:

NAMES_list
Jyo
Ras
Poo

根据这个列表,如果任何一个名称与我的上面的“main_data”表匹配,那么我想要删除包含它们的整行,结果应该如下所示

NAMES   AGE     LOC
Abid    27      Kar
Sus     28      Kar

有人能帮我用R语言实现这个吗?先谢过.. :)


我有同样的任务,但名字的格式为“姓,名”。对于那些有类似格式的人,您可能会发现需要从名称中删除空格才能使下面答案中的代码正常工作。 gsub(“”,x) 对我很管用。 - Pake
4个回答

62

使用%in%操作符:

main_data2 <- main_data[ ! main_data$NAMES %in% NAMES_list, ]

13

如果您恰好拥有一个 data.table(而不是 data.frame),并且您的 data.table 有一个 key,您可以使用非连接惯用语

library(data.table)
dat <- as.data.table(read.table(text="
NAMES   AGE     LOC
Jyo     23      Hyd
Abid    27      Kar
Ras     24      Pun
Poo     25      Goa
Sus     28      Kar", 
stringsAsFactors=FALSE, header=TRUE))

setkey(dat, NAMES)

to.remove <- c("Jyo","Ras","Poo")
dat[-dat[to.remove, which=TRUE]]
#   NAMES AGE LOC
#1:  Abid  27 Kar
#2:   Sus  28 Kar

当然,data.table 上使用另外两个 答案 也能奏效,但这个更加高效。

编辑

从data.table版本1.8.3开始,“!”前缀可用于“非连接”(请参见NEWS)。

dat[!to.remove]
   NAMES AGE LOC
1:  Abid  27 Kar
2:   Sus  28 Kar

2
+1 我们真的需要正确的非连接工作,不是吗:dat[-to.remove]。实际上,在内部实现它相当容易,但我还没有做到:( 这是FR#1384 - Matt Dowle

9

复制您的数据:

dat <- read.table(text="
NAMES   AGE     LOC
Jyo     23      Hyd
Abid    27      Kar
Ras     24      Pun
Poo     25      Goa
Sus     28      Kar", 
stringsAsFactors=FALSE, header=TRUE)

remove <- c("Jyo", "Ras", "Poo")

简单的子集操作:

dat[!dat$NAMES %in% remove, ]
  NAMES AGE LOC
2  Abid  27 Kar
5   Sus  28 Kar

以下是翻译的结果:

这是它的工作原理:使用否定和%in%的组合来返回一个逻辑向量,指示要保留的行:

!dat$NAMES %in% remove
[1] FALSE  TRUE FALSE FALSE  TRUE

我记得第一次看到这个结构时感到很惊讶。为什么!dat$NAMES会返回任何有用的信息呢?当然,这个构建的关键在于中缀运算符%in%先被计算,所以!只是一个逻辑非运算符。


...并且它被首先评估,因为它比%any%具有优先级 - January

1

如果您的main_data$NAMES中有唯一值,您也可以使用match

NAMES_list <- c("Jyo","Ras","Poo")
main_data <- main_data[-match(NAMES_list,main_data$NAMES),]
main_data
  NAMES AGE LOC
2  Abid  27 Kar
5   Sus  28 Kar

它将删除与main_data $ NAMES完全匹配的NAMES_list中的行。


-match()是什么意思(特别是减号)? - lanetrotro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接