我如何*排除*

时间:2012-11-29 23:43:35

标签: r pattern-matching k

我有一个包含很多日期的数据框(数据)。我希望从1970年之前删掉所有东西。我可以创建一个1970年之前的索引列表:

tmp <- which(data$data < '1970-01-01')
[1]  13446 102876 141199

我想创建一个删除这三行的新表。类似的东西:

data.after.1970 <- data[!tmp, ]

我知道我可以在 1970之后创建所有事件的向量,并与之匹配:

tmp <- which(data$data > '1970-01-01')
data.after.1970 <- data[tmp, ]

但我想知道我会用什么语法来排除项目​​。

更新

我终于做到了这一点:

tmp <- which(data$data > as.Date('1970-01-01'))
data.after.1970 <- data[tmp, ]

并仔细研究了一下。 which(data$data < as.Date('1970-01-01'))得到三个结果,但nrow(data) - nrow(data.after.1970)表示我删了45行。 summary(datae$date)清除了这一点:

summary(data$date)
        Min.      1st Qu.       Median         Mean      3rd Qu.         Max.         NA's 
"1933-07-01" "1989-01-25" "1992-07-09" "1992-05-03" "1996-06-10" "2006-09-14"         "42" 

由于我的目标是获得第二个数据集,所以如果我排除那些日期不好的数据,我可以比较我的结果,我实际上也希望删除那些带有NA值的数据。

想要知道我将使用什么语法来排除某些数字向量而不是包含它。

3 个答案:

答案 0 :(得分:5)

which为逻辑表达式的计算或逻辑向量本身中的TRUE项返回一个数字向量。也可以使用负索引来删除项目。在你的情况下可能看起来像:

tmp <- data[ which(data$data < '1970-01-01') ,  ] 

即。返回数据帧的所有行,“data”列,其中“data”列小于“1970-01-01”。你应该学会使用比“数据”更具体的名称。您不仅会通过为对象和具有该对象的元素使用相同的名称来创建混淆,而且还有一个函数“data”。那么,在你写作时,你的贫困观众应该如何知道你的意思,而不是10个月前的代码。

为了解决那些不喜欢使用which的上述说法的话,我会回答说它避免了“[”函数将返回条件为TRUE或NA的所有行的问题。 。您可以使用具有相同优势的subset,但不建议将其用于编程,仅用于交互式使用。您可以按子集的方式执行此操作,并添加一个消除NA值的子句:

tmp <- data[ data$data < '1970-01-01 & !is.na(data$data) , ]

......我认为使用which的版本比其他版本更“干净”。 which存在一个缺点,即在没有值为TRUE且使用负索引的情况下出现,在这种情况下,与使用dfrm[-which(condition) , ]的预期相反,将无法提供您想要的内容,而是空的向量。因此规则是:使用which但不使用否定索引。

答案 1 :(得分:1)

要解释一下,如果你跑:

data$date > '1970-01-01'

您将看到它返回TRUE/FALSE的逻辑向量,您可以使用它来选择所需的行。它的工作方式如下:

test <- 1:3
test[c(TRUE,FALSE,TRUE)]
# result
[1] 1 3

正如@DWin在他的回答中所指出的那样,当你有NA个值时会有一些警告,这些值也将被返回以及TRUE值。如:

test <- c(NA,1:3)
test > 2
# result
[1]    NA FALSE FALSE  TRUE
test[test>2]
# result
[1] NA  3

which语句仅返回所有TRUE索引,从而避免了NA值的问题。

test <- c(NA,1:3)

which(test>2)
# result - the fourth value of test is > 2
[1] 4

> test[4]
# result - return the fourth value of test
[1] 3

test[which(test>2)]
# result - return the fourth value of test as the 
# which statement has identified it is > 2
[1] 3

顺便说一下,我正在收集你可能实际上需要做的事情:

data$date > as.Date('1970-01-01')

...让你的榜样正常运作。当然,假设您的date列实际上也是Date对象,而不仅仅是纯文本。

答案 2 :(得分:0)

事实证明这实际上很简单。

data.after.1970 <- data[-tmp, ]

将创建一个新框架data.after.1970,其中包含data中的所有行,但与tmp中的索引匹配的行除外。