在R中检查数据列中的连续缺失值并根据相关列值排除它们的最佳方法是什么?

wrrgggsh  于 2023-06-03  发布在  其他
关注(0)|答案(2)|浏览(146)

我尝试用R语言编写一个数据集的代码,检查DAYS列是否有连续的数字,并打印出缺失的DAYS数字,如果DAYS列的两行之间缺失的连续数字的计数等于PERIOD列的相应最后一行中的计数+1,则将其从输出中排除。例如,考虑DAYS列163和165中的两行,其中缺失数字的计数为1。但在本例中,最后一行(DAYS为165)的PERIOD值为2,即(count+1)。因此,从输出中排除此缺失值(164)。但是,如果你看一下DAYS 170和172,你可以看到172的PERIOD值为1(不是2或count+1)。因此,显示此输出(171)。
这是数据集的前28行。

DAYS PERIOD
146 1
147 1
148 1
149 1
150 1
151 1
152 1
153 1
154 1
155 1
156 1
157 1
158 1
159 1
160 1
161 1
162 1
163 1
165 2
166 1
167 1
168 1
169 1
170 1
172 1
173 1
174 1
175 1

首先,创建一个预期DAYS值序列expected_days <- seq(min(hs$DAYS), max(hs$DAYS))
然后,查找缺失的DAYSmissing_days <- setdiff(expected_days, hs$DAYS)
下一步怎么做?

13z8s7eq

13z8s7eq1#

我使用Tidyverse工具做到了这一点:

设置示例数据

我稍微调整了您的数据,以显示该解决方案可以处理更长时间的缺失天数。

library(vroom)
library(dplyr)
library(tidyr)

test <-
  vroom(
    I(
"days period
161 1
162 1
163 1
166 3
167 1
168 1
169 1
170 1
172 1
"),
col_types = c("ii"))

在数据框中显式添加空天数

all_days <- min(test[["days"]]):max(test[["days"]])

frame <- tibble(days = all_days)

test <-
  right_join(test, frame, by = "days") |> 
  arrange(days)

test
#> # A tibble: 12 × 2
#>     days period
#>    <int>  <int>
#>  1   161      1
#>  2   162      1
#>  3   163      1
#>  4   164     NA
#>  5   165     NA
#>  6   166      3
#>  7   167      1
#>  8   168      1
#>  9   169      1
#> 10   170      1
#> 11   171     NA
#> 12   172      1

求连续缺失天数

test <- 
  mutate(test,
         no_na = xor(is.na(period), is.na(lag(period))),
          missingness_group = cumsum(no_na)) |> 
  select(-no_na)

test <- 
  group_by(test, missingness_group) |> 
  mutate(missing_days = 
           case_when(
             all(is.na(period)) ~ n(),
             TRUE               ~ 0)) |> 
  ungroup() |> 
  select(-missingness_group)

test
#> # A tibble: 12 × 3
#>     days period missing_days
#>    <int>  <int>        <dbl>
#>  1   161      1            0
#>  2   162      1            0
#>  3   163      1            0
#>  4   164     NA            2
#>  5   165     NA            2
#>  6   166      3            0
#>  7   167      1            0
#>  8   168      1            0
#>  9   169      1            0
#> 10   170      1            0
#> 11   171     NA            1
#> 12   172      1            0

删除所有天数的行

test <- mutate(test, extra_days = period - 1)

test <- fill(test, extra_days, .direction = "up")

test <-
  filter(test, !is.na(period) | missing_days > extra_days) |> 
  select(days, period)

test
#> # A tibble: 10 × 2
#>     days period
#>    <int>  <int>
#>  1   161      1
#>  2   162      1
#>  3   163      1
#>  4   166      3
#>  5   167      1
#>  6   168      1
#>  7   169      1
#>  8   170      1
#>  9   171     NA
#> 10   172      1

创建于2023-06-01使用reprex v2.0.2

piztneat

piztneat2#

取行差,看看它们是否等于PERIOD列值(忽略第一行):

hs[c(FALSE, diff(hs$DAYS) != hs$PERIOD[-1]), ]

Tidyverse版本:

library(dplyr)
hs |>
  filter(c(FALSE, diff(DAYS) != PERIOD[-1])

相关问题