在R中使用ifelse从数据集中删除不需要的行

4

我有一个数据集,我想要删除某些个体在第一年观测期内的11月份数据。是否可以使用ifelse实现?类似于:

ifelse(ID=="1" & Month=="11" and Year=="2006", "remove these rows",  
  ifelse(ID=="2" & Month=="11" & Year=="2007", "remove these rows",   
         "nothing"))  

一如既往地,感谢您的帮助!:)


1
这个问题可能有很多好的答案,但是如果有一个可重现的例子,所有的答案都会受益匪浅。 - BenBarnes
你要删除多少个人?是2个还是3个,还是更多?(如果是更多,应该使用%in%)。 - David Robinson
2个回答

10

如果你只想知道哪些需要移除,哪些不需要移除,那么你甚至不需要使用ifelse()语句。

ind <- (Month == "11") &
           ((ID == "1" & Year == "2006") | (ID == "2" & Year == "2007"))

ind如果为TRUE,则表示Month"11"并且其他两个子句中的任何一个也为TRUE

然后,你可以在任何通过[subset()进行的子集操作中使用!ind来删除这些样本。

dat <- data.frame(ID = rep(c("1","2"), each = 72),
                  Year = rep(c("2006","2007","2008"), each = 24),
                  Month = rep(as.character(1:12), times = 3))
ind <- with(dat, (Month == "11") & ((ID == "1" & Year == "2006") |
                                    (ID == "2" & Year == "2007")))
ind
dat2 <- dat[!ind, ]

这会给出什么结果

R> ind
  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
 [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
 [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE
[121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
R>     dat2 <- dat[!ind, ]
R> nrow(dat)
[1] 144
R> nrow(dat2)
[1] 140

就示例数据而言,这是正确的。


2
一个 data.table 解决方案,它将是时间和内存高效的(而且编码会稍微简单一些)。它将适用于大型数据集。如果列是整数而不是因子。
library(data.table)
DT <- data.table(ID = rep(1:2, each = 72),
          Year = rep(2006:2008, each = 24),
          Month = rep(1:12, times = 3))
# or you could use:   DT <- as.data.table(dat)
setkey(DT,ID,Year,Month)
DT[-DT[J(1:2,2006:2007,11),which=TRUE]]

谢谢提醒——我一直在处理字符/因子和-J(...)的问题。 - mnel
啊,我没有注意到字符/因子方面。如果DT的列是字符类型,则为:DT[-DT[J(c("1","2"),as.character(2006:2007),"11"),which=TRUE]]。如果它们是因子,则也可以工作(我认为会有警告),或者作为因子:DT[-DT[J(factor(1:2),factor(2006:2007),factor(11)),which=TRUE]] - Matt Dowle

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