r - 如何根据另一个数据帧的值填写数据帧中的 NA(平均值/中位数)?
问题描述
我有一个 df,我想为每个唯一 ID 运行关于它们在 Value 列中的值的 Shapiro 测试,并将结果放入数据表 (dt_table) 中。我还编写了几行代码,以便再次用每个唯一 ID 的平均值替换 NA。但是我真正想要检查 dt_table 并且如果列“accept_H1”为 TRUE,则将 NA 替换为中位数,但如果为 FALSE,则将 NA 替换为平均值
dput(df)
structure(list(ID = c("F1", "F1", "F1", "F1", "F1", "F1", "F1",
"F2", "F2", "F2", "F2", "F2", "F2", "F2", "F2", "F3", "F3", "F3",
"F3", "F3", "F3", "F3", "F3", "F3", "F4", "F4", "F4", "F4", "F4",
"F4", "F4", "F4"), Values = c(9.6, NA, 10.2, 9.8, 9.9, 9.9, 9.9,
1.2, 1.2, 1.8, 1.5, 1.5, 1.6, 1.4, NA, 3266, 3256, 7044, 6868,
NA, 3405, 3410, NA, 5567, 59.4, 56, 52.8, 52.4, 55.5, NA, NA,
53.6)), class = "data.frame", row.names = c(NA, -32L))
这是夏皮罗测试和我放置结果的数据表。
dt_list <- by(df, df$ID, function(sub) {
results <- shapiro.test(sub$Values)
data.table(
ID = sub$ID[1],
Wilk = results$statistic,
p_value = results$p.value,
accept_H1 = results$p.value <= 0.05
)
})
dt_table <- data.table::rbindlist(dt_list)
这些是用每个 ID 的平均值替换所有 NA 的几行代码。我想检查 data_table,例如,如果对于 F1,“accept_H1”列是 TRUE,那么我想用中位数替换 F1 的 NA,但它是 FALSE,然后我想用平均值替换它们。有人可以帮忙吗?
df %>%
group_by(ID) %>%
mutate(Values = ifelse(is.na(Values), mean(Values,na.rm=TRUE), Values))
解决方案
我们可能需要与“dt_table”进行连接或合并,然后使用if/else
条件。使用na.aggregate
from可能会更好,zoo
因为这更容易
library(data.table)
library(zoo)
setDT(df)[dt_table[, .(ID, accept_H1)], accept_H1 := accept_H1, on = .(ID)]
df[,Values := if(first(accept_H1)) na.aggregate(Values, FUN = median) else
na.aggregate(Values), ID][, accept_H1 := NULL][]
-输出
> df
ID Values
1: F1 9.600000
2: F1 9.883333
3: F1 10.200000
4: F1 9.800000
5: F1 9.900000
6: F1 9.900000
7: F1 9.900000
8: F2 1.200000
9: F2 1.200000
10: F2 1.800000
11: F2 1.500000
12: F2 1.500000
13: F2 1.600000
14: F2 1.400000
15: F2 1.457143
16: F3 3266.000000
17: F3 3256.000000
18: F3 7044.000000
19: F3 6868.000000
20: F3 3410.000000
21: F3 3405.000000
22: F3 3410.000000
23: F3 3410.000000
24: F3 5567.000000
25: F4 59.400000
26: F4 56.000000
27: F4 52.800000
28: F4 52.400000
29: F4 55.500000
30: F4 54.950000
31: F4 54.950000
32: F4 53.600000
ID Values
或者这也可以在不合并的情况下完成。即我们可以match
从'dt_table'中使用对应的'ID'分组值,使用索引提取'accept_H1'以用于if/else
条件
library(dplyr)
df %>%
group_by(ID) %>%
mutate(Values = if(dt_table$accept_H1[match(cur_group()$ID,
dt_table$ID)]) na.aggregate(Values, FUN = median) else
na.aggregate(Values)) %>%
ungroup
# A tibble: 32 x 2
ID Values
<chr> <dbl>
1 F1 9.6
2 F1 9.88
3 F1 10.2
4 F1 9.8
5 F1 9.9
6 F1 9.9
7 F1 9.9
8 F2 1.2
9 F2 1.2
10 F2 1.8
# … with 22 more rows
推荐阅读
- javascript - Bootstrap modal 运行一次,并且每次打开它都会运行一次
- amazon-web-services - AWS 上具有流出控制(背压)的队列
- java - 可以在 Java 中获取 2 种不同类型列表的方法
- r - 如何为 2 个共享成员的两个组创建一个公共 ID
- c++ - recv 总是返回 EAGAIN 但 tcpdump 显示内核丢弃了 0 个数据包
- django - Axios 正在向 Django 发送 OPTIONS 而不是 POST
- amazon-web-services - 如何计算 OpenID Connect 服务器的指纹?
- mongodb - 我无法使用 Express 和 Node 发布到我的 API
- pandas - 从字典词典到熊猫数据框
- python - 如何将具有多个变量的函数应用于 pandas 数据框的列(当无法更改 func 中 var 的顺序时)