使用 dplyr 按行用以前的值填充缺失值

2024-05-04

我正在使用 R 中的一个数据框,该数据框跨行有一些缺失值。数据框是下一个(dput添加到最后):

df
  id V1 V2 V3 V4
1 01  1  1  1 NA
2 02  2  1 NA NA
3 03  3  1 NA NA
4 04  4  1  2 NA

每一行都是不同的id。正如您所看到的,这些行缺少值。我想知道如何才能以这种风格完成数据框由于我的实际数据非常大,因此无需使用 reshape to long 或枢纽:

df
  id V1 V2 V3 V4
1 01  1  1  1  1
2 02  2  1  1  1
3 03  3  1  1  1
4 04  4  1  2  2

我试图使用fill from tidyr但在行级别我遇到了问题。我看过一些帖子,其中它与dplyr功能across但我找不到它。我尝试过使用group_by(id) and rowwise但我还没有成功。也只有以以下开头的变量/列V应填充以前的值。

接下来是数据:

#Data
df <- structure(list(id = c("01", "02", "03", "04"), V1 = c(1, 2, 3, 
4), V2 = c(1, 1, 1, 1), V3 = c(1, NA, NA, 2), V4 = c(NA, NA, 
NA, NA)), class = "data.frame", row.names = c(NA, -4L))

非常感谢您抽出时间。


一种解决方案可以使用na.locf包中的函数zoo结合purrr::pmap行操作中的函数。na.locf取最近的非NA评估并替换所有即将到来的NA值由此。只是作为一个提醒c(...)在两种解决方案中都捕获了所有值V1:V4在每次迭代的每一行中。不过我排除了id两者中的列,因为它不参与我们的计算。

library(zoo)
library(purrr)

df %>%
  mutate(pmap_df(., ~ na.locf(c(...)[-1])))

  id V1 V2 V3 V4
1 01  1  1  1  1
2 02  2  1  1  1
3 03  3  1  1  1
4 04  4  1  2  2

或者我们可以使用coalesce函数来自dplyr。我们可以替换每一个NA每行中最后一个非值NAvalue,我们之前做的事情na.locf。然而这个解决方案有点冗长:

df %>%
  mutate(pmap_df(., ~ {x <- c(...)[!is.na(c(...))]; 
  coalesce(c(...), x[length(x)])}))

  id V1 V2 V3 V4
1 01  1  1  1  1
2 02  2  1  1  1
3 03  3  1  1  1
4 04  4  1  2  2

或者你也可以使用这个:

library(purrr)

df %>%
  mutate(across(!id, ~ replace(., is.na(.), invoke(coalesce, rev(df[-1])))))

  id V1 V2 V3 V4
1 01  1  1  1  1
2 02  2  1  1  1
3 03  3  1  1  1
4 04  4  1  2  2

可以忽略该警告消息。它实际上是因为我们有 6 个而产生的NA值而是应用的结果dplyr::coalesce每个向量上有 1 个元素,从而用 4 个元素代替 6 个槽。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 dplyr 按行用以前的值填充缺失值 的相关文章

随机推荐