【问题标题】:R refill NA values within group using dplyrR使用dplyr在组内重新填充NA值
【发布时间】:2017-04-17 01:30:08
【问题描述】:

我有以下数据框:

library(dplyr)

dat <- data_frame(id = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
                     3L, 5L, 5L, 7L, 7L, 7L, 8L, 8L, 8L, 10L), 
              wish1 = c(4L, NA, NA, 1L, NA, 1L, NA, NA, NA, 
                        NA, -1L, 8L, NA, 1L, -1L, NA, 4L, 
                        NA, NA, -1L), 
              wish2 = c(1L, NA, NA, 1L, NA, 1L, NA, NA, NA, 
                        NA, -1L, 1L, NA, 2L, -1L, NA, 2L, NA, NA, 1L), 
              participate = c(NA, 1L, NA, NA, 1L, NA, NA, 1L, NA, NA, NA, 
                              NA, 1L, NA, 4L, NA, NA, NA, 1L, NA))

我想在每个组中将变量participateNAs 替换为同一组中可用的值。如果组内没有值,则NA 可以保留。

我需要类似的东西:

df <- data %>% group_by(id) %>% 
    mutate(participate = (participate, na.rm = TRUE))

不幸的是,如果没有 sum 之类的功能或任何其他功能,这将无法工作。

【问题讨论】:

  • participate 只有 19 长,因此代码不会按原样运行。也就是说,dat %&gt;% group_by(id) %&gt;% mutate(participate = first(na.omit(participate))) 之类的东西应该可以工作。
  • @alistaire 我尝试了您的代码并收到此错误Error in mutate_impl(.data, dots) : Unsupported vector type language。你有什么想法吗?
  • @alistaire 我发现如果使用arrange先将数据框按idparticipate排序,就没有必要使用na.omit了。这是代码:dat %&gt;% arrange(id, participate) %&gt;% group_by(id) %&gt;% mutate(participate = first(participate))。这可能是迄今为止最简洁的解决方案。
  • 或基础:dat$participate &lt;- ave(dat$participate, dat$id, FUN = function(x){sort(x)[1]}) 或 data.table:setDT(dat)[, participate := sort(participate)[1], by = id][]
  • 我现在更正了代码。感谢您的提示!

标签: r dplyr


【解决方案1】:

可能有更简洁或优雅的方式,但我想分享一些想法。

解决方案 1:使用 tidyr 的填充功能

library(tidyr)

# the fill function can fill the NA based on the previous entry
dat2 <- dat %>%
  arrange(id, participate) %>%
  group_by(id) %>%
  fill(participate)

解决方案 2:确定填充值,然后使用 left_join

# dat_temp is a summary data frame showing the fill values
dat_temp <- dat %>%
  arrange(id, participate) %>%
  group_by(id) %>%
  slice(1) %>%
  select(id, participate)

# Join dat_temp to dat2
dat2 <- dat %>%
  left_join(dat_temp, by = "id") %>%
  select(-participate.x) %>%
  rename(participate = participate.y)

解决方案 3:对数据框进行排序,然后根据第一个值填充 NA

此解决方案基于 alistaire 的评论

dat2 <- dat %>% 
  arrange(id, participate) %>%
  group_by(id) %>% 
  mutate(participate = first(participate))

【讨论】:

  • 感谢您将 cmets 总结为三种不同的解决方案。虽然更喜欢第一个,但我仍然从其他两个中学到了很多东西!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-22
  • 2017-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多