创建一个新的数据框清理 NA 并按 r 中的列更新

Create a new data frame cleaning NA and updating by column in r

想象一下,我们拥有来自代表不同情节的任务的数据,并且每个情节中都发生了不同的事情。我想根据以下逻辑制作一个矢量,我想组织每个试验的信息 t 仅当可用时。

t <- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2)
p <- c(NA,NA,NA,8,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,2,NA,NA,NA,NA,NA,NA,NA,NA)
p_1 <- c(NA,NA,NA,NA,NA,NA,NA,11,NA,13,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,8,NA,NA,NA,NA)
b <- c(NA,NA,NA,NA,NA,7,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,10,NA,NA,NA,NA,NA,NA)
rw <- c(NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,-1,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,-1)
a <- c(NA,NA,1,NA,NA,1,NA,1,NA,1,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,1,NA,0,NA,NA,NA,NA)
is <- c(NA,NA,NA,FALSE,NA,NA,NA,TRUE,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,TRUE,NA,NA,NA,NA,NA,NA,NA,NA)
v <- data.frame(t,p,p_1,b,rw,a,is)

#which returns the following data frame:

   t  p p_1  b rw  a    is
1  1 NA  NA NA NA NA    NA
2  1 NA  NA NA NA NA    NA
3  1 NA  NA NA NA  1    NA
4  1  8  NA NA NA NA FALSE
5  1 NA  NA NA NA NA    NA
6  1 NA  NA  7 NA  1    NA
7  1 NA  NA NA NA NA    NA
8  1 NA   1 NA NA  1  TRUE
9  1 NA  NA NA NA NA    NA
10 1 NA  13 NA NA  1    NA
11 1 NA  NA NA NA NA    NA
12 1 NA  NA NA NA NA    NA
13 1 NA  NA NA NA NA    NA
14 1 NA  NA NA NA NA    NA
15 1 NA  NA NA -1 NA    NA
16 2 NA  NA NA NA NA    NA
17 2 NA  NA NA NA NA    NA
18 2 NA  NA NA NA NA    NA
19 2  1  NA NA NA NA  TRUE
20 2 NA  NA NA NA NA    NA
21 2 NA  NA 10 NA  1    NA
22 2 NA  NA NA NA NA    NA
23 2 NA   8 NA NA  0    NA
24 2 NA  NA NA NA NA    NA
25 2 NA  NA NA NA NA    NA
26 2 NA  NA NA NA NA    NA
27 2 NA  NA NA -1 NA    NA

我的最终目标是读取 table 并在每一步生成一个数据框或一个包含更新数据的向量,直到剧集结束,读起来像这样。

1 8 NA NA NA 1 FALSE
1 8 NA 7  NA 1 FALSE
1 8  1 7  NA 1 TRUE
1 8 13 7  NA 1 TRUE
1 8 13 7  -1 1 TRUE
2 1 NA NA NA 1 TRUE
2 1 NA 10 NA 1 TRUE
2 1  8 10 NA 0 TRUE
2 1  8 10 -1 0 TRUE

我尝试制作一个不带 NA 的向量,然后尝试将它们连接起来,但由于行的大小不同,所以它不起作用。

我也尝试过,基于这个 dplyr 但我无法让它工作


library(dplyr)

test1 <- v %>% filter(if_all(contains('t','p','p_1','b','rw','a','is'), Negate(is.na)))


> test1 <- v %>% filter(if_all(contains('t','p','p_1','b','rw','a','is'), Negate(is.na)))
Error: Problem with `filter()` input `..1`.
ℹ Input `..1` is `if_all(contains("t", "p", "p_1", "b", "rw", "a", "is"), Negate(is.na))`.
x unused arguments ("b", "rw", "a", "is")
Run `rlang::last_error()` to see where the error occurred.

有什么想法吗?

提前致谢!

尝试使用 dplyrtidyr::fill

library(dplyr)
library(tidyr)

v |> 
  filter(rowSums(!is.na(v))>1) |>
  group_by(t) |>
  fill(everything())

# A tibble: 10 x 7
# Groups:   t [2]
       t     p   p_1     b    rw     a is   
   <int> <int> <int> <int> <int> <int> <lgl>
 1     1    NA    NA    NA    NA     1 NA   
 2     1     8    NA    NA    NA     1 FALSE
 3     1     8    NA     7    NA     1 FALSE
 4     1     8     1     7    NA     1 TRUE 
 5     1     8    13     7    NA     1 TRUE 
 6     1     8    13     7    -1     1 TRUE 
 7     2     1    NA    NA    NA    NA TRUE 
 8     2     1    NA    10    NA     1 TRUE 
 9     2     1     8    10    NA     0 TRUE 
10     2     1     8    10    -1     0 TRUE 

这实际上与 George Savva 的方法相同,但他比我先做。它使用 zoo::na.locf 而不是 tidyr。我会提供它作为替代方案,但我不会说它更好。

library(dplyr)

v %>% 
  # Remove any rows where all of the values are NA
  filter(!(is.na(p) & is.na(p_1) & 
             is.na(b) & is.na(rw) & 
             is.na(a) & is.na(is))) %>%
  # Group by ID
  group_by(t) %>%
  # Perform a "last one carried forward", which will replace any missing
  # values in a column with the last non-missing value, if available.
  mutate_at(c("p", "p_1", "b", "rw", "a", "is"), 
            zoo::na.locf, 
            na.rm = FALSE) %>% 
  ungroup() %>% 
  # Remove rows that have a missing `p`
  filter(!is.na(p))
#> # A tibble: 9 x 7
#>       t     p   p_1     b    rw     a is   
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl>
#> 1     1     8    NA    NA    NA     1 FALSE
#> 2     1     8    NA     7    NA     1 FALSE
#> 3     1     8     1     7    NA     1 TRUE 
#> 4     1     8    13     7    NA     1 TRUE 
#> 5     1     8    13     7    -1     1 TRUE 
#> 6     2     2    NA    NA    NA    NA TRUE 
#> 7     2     2    NA    10    NA     1 TRUE 
#> 8     2     2     8    10    NA     0 TRUE 
#> 9     2     2     8    10    -1     0 TRUE