r - 分组管理 NA 的整洁方式?
问题描述
我的问题如下:
我有一个小标题,我想用 3 种不同的情况进行修改:
- 组中的所有值都是
NA
- 至少有一个但不是全部
NA
。在这种情况下,替换NA
为任意值(例如0.5
:) - 没有
NA
示例:(带group_by
ind
)
a1 = c(0.3,0.1,NA,0.7,0.2)
a2 = rep(NA,5)
a3 = c(0.1,0.3,0.5,0.7,0.8)
tibble(ind = c(rep("A",5),rep("B",5),rep("C",5)),
value = c(a1,a2,a3)
组段A
应产生 c(0.3,0.1, 0.5 ,0.7,0.2)
组的一部分B
应该产生代表(NA,5)
组的一部分C
应该保持不变
我已经尝试过if
,ifelse
和case_when
语句,但我认为我遗漏了一些非常明显的东西。感谢所有帮助。
解决方案
编辑:
这是一种破解方法,尽管我知道有一种更简洁的方法:
library(dplyr)
df %>%
group_by(ind) %>%
mutate_if(is.logical, as.numeric) %>%
mutate(a1 = case_when(is.na(a1) & sum(is.na(a1)) < length(a1) ~ 0.5, TRUE ~ a1),
a2 = case_when(is.na(a2) & sum(is.na(a2)) < length(a2) ~ 0.5, TRUE ~ a2),
a3 = case_when(is.na(a3) & sum(is.na(a3)) < length(a3) ~ 0.5, TRUE ~ a3))
Edit2:这是更简洁的方法
point_five <- function(x){
x = case_when(is.na(x) & sum(is.na(x)) < length(x) ~ 0.5, TRUE ~ x)
}
df %>%
group_by(ind) %>%
mutate_if(is.logical, as.numeric) %>%
mutate(across(.cols = c(a1:a3), ~ point_five(.)))
这给了我们:
# A tibble: 5 x 4
# Groups: ind [1]
ind a1 a2 a3
<chr> <dbl> <dbl> <dbl>
1 A 0.3 NA 0.1
2 A 0.1 NA 0.3
3 A 0.5 NA 0.5
4 A 0.7 NA 0.7
5 A 0.2 NA 0.8
如果我们有df2
,包含两个组 for ind
,group_by
将给我们:
ind a1 a2 a3
<chr> <dbl> <dbl> <dbl>
1 A 0.3 NA 0.1
2 A 0.5 NA 0.3
3 A 0.5 NA 0.5
4 A 0.7 NA 0.7
5 A 0.2 NA 0.8
6 B 0.5 NA 0.1
7 B 0.5 NA 0.3
8 B 0.5 NA 0.5
9 B 0.5 NA 0.7
10 B 0.2 NA 0.8
df2
structure(list(ind = c("A", "A", "A", "A", "A", "B", "B", "B",
"B", "B"), a1 = c(0.3, 0.5, NA, 0.7, 0.2, NA, 0.5, NA, NA, 0.2
), a2 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), a3 = c(0.1,
0.3, 0.5, 0.7, 0.8, 0.1, 0.3, 0.5, 0.7, 0.8)), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"))
推荐阅读
- java - 我是否必须阻止循环操作处理程序调用
- java - 如何在 Spring Boot Cors 中设置标题?
- ios - 如何在另一个故事板中快速在 xib 文件中显示新控制器
- apache-spark - pyspark union over RDDs 的组合
- javascript - IntelliJ 显示无效 HTML 警告 - 来自不同模块的源
- node.js - ExpressJS 路由将参数保存到 Store.js
- android - 添加/编辑活动的最佳实践
- javascript - 如何在javascript中实现分层多级数据表?
- eclipse - 克隆 GIT 存储库时出现“Auth Fail”错误
- sql - Check the example below. Trying to make a sql query which will work in Derby database