1

我有一个包含邮政编码和状态列(等等)的数据集。它很大但并不可怕(4M 行,70 列),但过滤错误的观察需要很长时间。具体来说,我试图放弃邮政编码与州不相加的观察结果(例如,新泽西州邮政编码以 0 开头,但数据中的许多邮政编码以 7 开头)。这是我目前的方法,但我相信必须有更快的方法。我们欢迎所有的建议!

df_clean <- df_tmp %>%  
  filter(!(startsWith(zip, c("7", "8")) & state == "NJ")) %>%
  filter(!(startsWith(zip, c("0", "1")) & state == "FL")) %>%
  filter(!(startsWith(zip, "4") & state == "ME")) %>%
  filter(!(startsWith(zip, c("1", "2")) & state == "MA")) %>%
  filter(!(startsWith(zip, "6") & state == "CT")) 

我希望它是不言自明的,但如果样本数据集会有所帮助,请告诉我。谢谢!

4

2 回答 2

1

问题是,如果数据框很大,每个过滤器都会删除一部分,然后将仍然很大的数据集传递给下一个过滤器,所以它会变慢。

如果您可以将所有条件组合在一个过滤器表达式中,它将运行得更快。像这样:

df_clean <- df_tmp %>%  
  filter(
    !(startsWith(zip, c("7", "8")) & state == "NJ") |
    !(startsWith(zip, c("0", "1")) & state == "FL") |
    !(startsWith(zip, "4") & state == "ME") |
    !(startsWith(zip, c("1", "2")) & state == "MA") |
    !(startsWith(zip, "6") & state == "CT")
  )

不要费心在 | 之前用 () 包围 & 表达式,因为 | 反正优先级较低。这样你的表达就变得更具可读性。

于 2020-03-05T15:39:28.223 回答
1

这是一种更加程序化的方法,它涉及按状态创建具有正确起始数字的查找表,将其与您的数据连接起来,并删除起始数字与该状态的预期数字不匹配的所有行。

digits_by_state <- data.frame(state = c("NJ", "FL", "ME", "MA", "CT"), 
                              correct_digit = c(0,3,0,0,0))

df_clean <- df_tmp %>%
  mutate(starting_digit = as.integer(substr(zip, 1, 1))) %>%
  left_join(digits_by_state) %>%
  filter(starting_digit == correct_digit)
于 2020-03-05T16:06:54.500 回答