从数据框中删除特定行

时间:2011-07-06 19:11:23

标签: r dataframe

我正在处理一些美国政府数据,这些数据包含很长的城市和邮政编码列表。 完成一些工作后,数据采用以下格式。

dat1 = data.frame(keyword=c("Bremen", "Brent", "Centreville, AL", "Chelsea, AL", "Bailytown, Alabama", "Calera, Alabama",
              "54023", "54024"), tag=c(rep("AlabamCity",2), rep("AlabamaCityST",2), rep("AlabamaCityState",2), rep("AlabamaZipCode",2)))
dat1

但是,某些关键字无法正常运行。因此,在下面的示例中,有两个“邮政编码” 被标记为'AlabamaCity'和'AlabamaCityState'。出于某种原因,政府的原始数据集有几个zipcodes 没有与其他邮政编码正确分组。

dat2 = data.frame(keyword=c("Bremen", "Brent", "50143", "Chelsea, AL", "Bailytown, Alabama", "52348",
              "54023", "54024"), tag=c(rep("AlabamCity",2), rep("AlabamaCityST",2), rep("AlabamaCityState",2), rep("AlabamaZipCode",2)))
dat2

我想知道如何迭代整个关键字列表并删除所有带有数值的行(它们实际上保存为字符 值)没有'AlabamaZipCode'标签。所以以前的数据应该看起来像。

dat3 = data.frame(keyword=c("Bremen", "Brent", "Chelsea, AL", "Bailytown, Alabama", "54023", "54024"), 
          tag=c(rep("AlabamCity",2), rep("AlabamaCityST",1), rep("AlabamaCityState",1), rep("AlabamaZipCode",2)))
dat3

挑战似乎是我想要保留某些数值以及我想要删除的其他数值。 任何人都可以提供帮助。

3 个答案:

答案 0 :(得分:10)

我认为两个grepl表达式可以解决这个问题:

> dat2[ !( grepl("City", dat2$tag) &  grepl("^\\d", dat2$keyword) ) , ]
             keyword              tag
1             Bremen       AlabamCity
2              Brent       AlabamCity
4        Chelsea, AL    AlabamaCityST
5 Bailytown, Alabama AlabamaCityState
7              54023   AlabamaZipCode
8              54024   AlabamaZipCode

您正在keyword

中删除tag和“城市”中有数字的行

答案 1 :(得分:5)

它有助于将数据存储为字符,而不是因素:

dat2 <- data.frame(keyword=c("Bremen", "Brent", "50143", "Chelsea, AL", 
                             "Bailytown, Alabama", "52348", "54023", "54024"),   
                   tag=c(rep("AlabamCity",2), rep("AlabamaCityST",2), 
                         rep("AlabamaCityState",2), rep("AlabamaZipCode",2)),
                   stringsAsFactors = FALSE) ## note this bit

现在我们可以将keyword转换为数字,如果它不是字符格式的数字,我们会得到NA

want <- with(dat2, as.numeric(keyword))

给了我们这个:

> (want <- with(dat2, as.numeric(keyword)))
[1]    NA    NA 50143    NA    NA 52348 54023 54024
Warning message:
In eval(expr, envir, enclos) : NAs introduced by coercion

你可以忽略警告或禁止它,但不要随意使用它,因为它可以掩盖问题:

suppressWarnings(want <- with(dat2, as.numeric(keyword)))

最后一步是选择{{1>} want NA等于{{{{}}的元素1}},我们使用keyword执行:

"AlabamaZipCode"

选择我们不想要的行,因此我们需要否定上述内容,将&转为(!is.na(want) & (dat2$tag != "AlabamaZipCode")) ,反之亦然:

TRUE

把这些放在一起我们有:

FALSE

给出:

!(!is.na(want) & (dat2$tag != "AlabamaZipCode"))

完整的解决方案是:

dat2[!(!is.na(want) & (dat2$tag != "AlabamaZipCode")), ]

答案 2 :(得分:2)

这是您可以考虑的一种(略微复杂的)方法。首先,为每行创建一个标识列。这将有助于子集化。其次,创建符合条件的那些id的向量。最后,将这些id从您的最终数据中分配出来。

您发布的数据默认为因素,而不是字符数据,因此我已将其考虑在内。如果这与您的实际数据不同,则必须进行相应调整。此外,当我将数据转换为数字时,会生成NA。生成警告消息,但我们可以忽略该位。

#Generate an ID column
dat4$id <- 1:nrow(dat4)

#Create a vector of the id's that match your criteria'
outliers <- dat4[as.character(dat4$tag) != "AlabamaZipCode" & !(is.na(as.numeric(as.character(dat4$keyword)))) , "id"]

subset(dat4, !(id %in% outliers), select = 1:2)
             keyword              tag
1             Bremen       AlabamCity
2              Brent       AlabamCity
4        Chelsea, AL    AlabamaCityST
5 Bailytown, Alabama AlabamaCityState
7              54023   AlabamaZipCode
8              54024   AlabamaZipCode

实际上,您可以将所有这些缩短为以下内容并避免生成ID。

dat4[!(as.character(dat4$tag) != "AlabamaZipCode" & !(is.na(as.numeric(as.character(dat4$keyword))))) , ]