我有这个玩具数据框架:
df <- data.frame(id=c(1,1,2,3,4,4),p_id=c(1001,1001,1002,1003,1004,1004),x=c(1,NA,1,2,NA,1),y=c(NA,5,4,NA,6,NA),z=c(NA,NA,2,3,NA,4))
id p_id x y z
1 1001 1 NA NA
1 1001 NA 5 NA
2 1002 1 4 2
3 1003 2 NA 3
4 1004 NA 6 NA
4 1004 1 NA 4
我想获得具有唯一“p_id”行的最终输出,并且从x,y和z(理想情况下,应该可以在任意数量的列上工作)中删除不需要的NA值。示例输出:
p_id x y z
1001 1 5 NaN
1002 1 4 2
1003 2 NaN 3
1004 1 6 4
我正在做这个快速解决方法(不确定最佳方法):
df %>% select(-id) %>% group_by(p_id) %>% summarise_all(funs(mean),na.rm=T) %>% ungroup()
但是,当应用于大型数据帧(2500 x 650)时,此解决方法非常慢,并且会为正常单元格创建不需要的NA。同样对于上下文,此df中具有NA的重复p_id行来自扩展函数。
答案 0 :(得分:1)
按“ID”列进行分组后,如果每个组中该列中的所有元素均为summarise_all
,则通过创建if/else
条件返回NaN
来执行NA
或者取非NA元素(在这个例子中,只有一个非NA元素,所以我们将它子集化)
df %>%
group_by(id, p_id) %>%
summarise_all(funs(if(all(is.na(.))) NaN else .[!is.na(.)]))
# A tibble: 4 x 5
# Groups: id [?]
# id p_id x y z
# <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1 1001 1 5 NaN
#2 2 1002 1 4 2
#3 3 1003 2 NaN 3
#4 4 1004 1 6 4
如果每个组ID组合的NA值超过非NA值,那么我们可以使用mean
(如OP的帖子所示)
df %>%
group_by(id, p_id) %>%
summarise_all(funs(if(all(is.na(.))) NaN else mean(., na.rm = TRUE)))
答案 1 :(得分:0)
您可以使用tidyr::fill()
后跟summarize
df %>%
group_by(id) %>%
fill(x,y,z, .direction = "up") %>%
summarise_all(first)
#> # A tibble: 4 x 5
#> id p_id x y z
#> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 1001 1 5 NA
#> 2 2 1002 1 4 2
#> 3 3 1003 2 NA 3
#> 4 4 1004 1 6 4