【问题标题】:How to delete rows from a data.frame, based on an external list, using R?如何使用 R 基于外部列表从 data.frame 中删除行?
【发布时间】:2012-10-22 13:29:14
【问题描述】:

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

我有一个 data.frame (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 实现这一目标? 提前谢谢.. :)

【问题讨论】:

  • 我有同样的任务,但名称格式为“Last, First”。对于那些具有类似格式的人,您可能会发现可能需要从名称中删除空格才能使下面的答案中的代码正常工作。 gsub(" ","",x) 帮了我大忙。

标签: r dataframe


【解决方案1】:

使用%in%:

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

【讨论】:

  • 感谢您的帮助。我会试试看。
【解决方案2】:

如果碰巧你实际上有一个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

当然,另一个two answers 也可以在data.table 上工作,但这应该更有效。


编辑

从 data.table 版本 1.8.3 开始,“!”前缀可用于“不加入”(参见NEWS)。

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

【讨论】:

  • +1 我们真的需要适当的不加入工作,不是吗:dat[-to.remove]。它实际上很容易在内部实现,但我还没有做到:(它是FR#1384.
【解决方案3】:

复制您的数据:

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% 首先被评估,所以 ! 只是一个逻辑 NOT 运算符。

【讨论】:

  • ...它首先被评估,因为它有 precedence 超过 %any%
【解决方案4】:

如果您的 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

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

【讨论】:

  • -match() 是什么意思(尤其是减号)
猜你喜欢
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多