如何删除 R 中带有连续零的行?

问题描述 投票:0回答:2

我有一个 R 时间序列数据表,其中包含年份、位置、物种和人口计数的列。

我一直在试图找到一种方法来删除存在多个(三个)连续人口计数为零的时间序列(或只是年份)。我很惊讶还没有一个函数可以做到这一点,但我还没有找到任何东西。

例如,以下是在 R 中生成的示例数据:

dt <- data.table(
  Species = c(rep("A", 6), rep("B", 6), rep("C", 6)),
  Location = c("X", "X", "X", "X", "Y", "Y", "X", "X", "X", "X", "X", "X", "Y", "Y", "Y", "Y", "Y", "Y"),
  Year = c(2010, 2011, 2012, 2013, 2010, 2011, 2010, 2011, 2012, 2013, 2014, 2015, 2010, 2011, 2012, 2013, 2014, 2015),
  Count = c(3, 4, 10, 1, 5, 0, 3, 0, 0, 0, 2, 1, 0, 10, 11, 14, 12, 9)
)

根据这些数据,我预计位置 X 的物种 B 将被删除,但其他物种将被保留。

我一直在尝试编写自己的函数,但没有成功,我最终编写了一个函数来创建 TRUE/FALSE 列,在每个位置-物种组合的 for 循环中使用它,然后过滤掉时间序列包含其中的 TRUE 值。但它不起作用,我认为我让它变得比需要的更复杂。

consecutive_zeros <- function(dt, Count) {
  Count <- dt$Count
for (i in 1:nrow(dt)-2) { 
  consecutive_zeros <- dt$Count[i] + dt$Count[i+1] + dt$Count[i+2] == 0
  dt$consecutive_zeros[i] <- consecutive_zeros
}
return(dt)
} 

我确信有人之前一定需要做类似的事情...任何建议将不胜感激!

r data.table data-cleaning
2个回答
0
投票

dplyr
中,您可以创建一个临时变量(
three0
)然后过滤:

dt %>%
  mutate(three0 = n() <= 2, 
         .by = c(Species, Count)) %>%
  filter(!any(!three0), 
         .by = c(Species, Location)) %>% 
  select(-three0)

输出:

   Species Location Year Count
 1:       A        X 2010     3
 2:       A        X 2011     4
 3:       A        X 2012    10
 4:       A        X 2013     1
 5:       A        Y 2010     5
 6:       A        Y 2011     0
 7:       C        Y 2010     0
 8:       C        Y 2011    10
 9:       C        Y 2012    11
10:       C        Y 2013    14
11:       C        Y 2014    12
12:       C        Y 2015     9

0
投票
dt[, 
   if (any(frollapply(Count, FUN = is_all0, n = 3, fill = -1) > 0)) NULL else .SD, 
   by = .(Species, Location)]


#     Species Location  Year Count
#      <char>   <char> <num> <num>
#  1:       A        X  2010     3
#  2:       A        X  2011     4
#  3:       A        X  2012    10
#  4:       A        X  2013     1
#  5:       A        Y  2010     5
#  6:       A        Y  2011     0
#  7:       C        Y  2010     0
#  8:       C        Y  2011    10
#  9:       C        Y  2012    11
# 10:       C        Y  2013    14
# 11:       C        Y  2014    12
# 12:       C        Y  2015     9

有很多方法可以实现检查三个数字是否全为 0 的函数。以下是一些示例:

is_all0 <- \(x) max(x) == 0
is_all0 <- \(x) all(x == 0)
is_all0 <- \(x) Reduce(bitwOr, x) == 0
© www.soinside.com 2019 - 2024. All rights reserved.