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

我正在处理一个数据框,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 或 pivot 的情况下以这种样式完成数据框,因为我的真实数据非常大

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

我试图使用fillfromtidyr但在行级别我遇到了问题。我看过一些帖子,它与dplyr函数一起使用,across但我找不到它。我试过使用group_by(id)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结合使用pmapna.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最后一个非NA值替换每一行中的每个值,这是我们之前用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值而产生的,但是coalesce在每个向量上应用的结果是 1 个元素,导致 4 个元素替换 6 个插槽。

  • 看看这里。你要出名了!&lt;/sf/ask/4823929491/?noredirect=1#comment121793354_68914759&gt;

回答

使用的一种选择dplyr可能是:

df %>%
 mutate(across(-id, ~ ifelse(is.na(.), coalesce(!!!select(., V4:V1)), .)))

  id V1 V2 V3 V4
1  1  1  1  1  1
2  2  2  1  1  1
3  3  3  1  1  1
4  4  4  1  2  2

  • I always called it the "bang bang bang" operator, but "big bang" is so much better.

以上是使用dplyr按行用以前的值填充缺失值的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>