r - 获取同一轮中的两行或多行价值差异小于 20%
问题描述
假设我有这样的数据:
# Data frame
df <- data.frame(round = factor(c(rep(1,4),rep(2,3),rep(3,4),rep(4,2))),
value = c(100,150,200,250,200,160,900,500,600,900,1200,100,120),
SE = c(1.3,1.5,0.7,2,1,2,1,1,1,0.5,0.75,20,3))
df
round value SE
1 1 100 1.30
2 1 150 1.50
3 1 200 0.70
4 1 250 2.00
5 2 200 1.00
6 2 160 2.00
7 2 900 1.00
8 3 500 1.00
9 3 600 1.00
10 3 900 0.50
11 3 1200 0.75
12 4 100 20.00
13 4 120 3.00
- 我想在同一轮中获得 2 行或更多行的值差异小于 20%(例如在第 1 轮:将排除所有行,第 2 轮:将排除 value = 900 的行,并且在轮3:将排除 value = 900 和 1200 的行)
到目前为止,我尝试过的是:
library(dplyr)
df %>%
group_by(Round) %>%
mutate(medians = median(value),
deviation = abs(value - medians) * 100 / medians) %>%
mutate(rowcounts = n()) %>%
mutate(passORfailed = ifelse(
rowcounts == 2,
ifelse((max(value) - min(value)) * 100 / max(value) > 20, "failed", "pass"),
ifelse(deviation > 20, "failed", "pass"))) %>%
filter(passORfailed != "failed") %>%
filter(sum(rowcounts) != 1)
结果:
# A tibble: 8 x 7
# Groups: round [4]
round value SE medians deviation rowcounts passORfailed
<fct> <dbl> <dbl> <dbl> <dbl> <int> <chr>
1 1 150 1.5 175 14.3 4 pass # -> not right
2 1 200 0.7 175 14.3 4 pass # -> not right
3 2 200 1 200 0 3 pass # -> ok
4 2 160 2 200 20 3 pass # -> ok
5 3 600 1 750 20 4 pass # -> not right (500 was excluded)
6 3 900 0.5 750 20 4 pass # -> not right
7 4 100 20 110 9.09 2 pass # -> ok
8 4 120 3 110 9.09 2 pass # -> ok
正如您所看到的,当行数为偶数且 >3 时,事情变得疯狂。问题是当我使用中位数时,为标准计算的实际值是一半(由于两个中心值之间的平均值)。无论如何调整代码以使其在所有情况下都成为可能?
- 如果可能,如何调整代码以在值 +- SE 范围内计算此数据?
如果问题不清楚,我很抱歉,但我已尽力解释。问候
解决方案
这是一种方法,我们在一轮中生成每个可能的对,然后仅过滤彼此相距 20% 以内的行。它的逻辑与您的逻辑略有不同,因此它会导致更少的匹配,但如果您使用不同的阈值(例如 +/- 35%,而不是 +/- 20%),作为替代方法可能会很有用。
df <- df %>% mutate(row = row_number())
df %>%
left_join(df, by = "round") %>%
mutate(ratio = value.x / value.y) %>%
filter(row.x != row.y,
ratio %>% between(1/1.2, 1.2))
这是解决问题第二部分的变体。我为每个计算值 +/- SE 并在每一轮中找到重叠的行对。
df <- df %>%
mutate(row = row_number()) %>%
mutate(low = value - SE,
high = value + SE)
df %>%
left_join(df, by = "round") %>%
filter(row.x != row.y,
(high.x >= low.y & high.x <= high.y) | (low.x >= low.y & low.x <= high.y))
round value.x SE.x row.x low.x high.x value.y SE.y row.y low.y high.y
1 4 100 20 12 80 120 120 3 13 117 123
2 4 120 3 13 117 123 100 20 12 80 120
推荐阅读
- database - 使用查询将数据复制到 postgresql 中的 json 文件中时,将单个“\”的记录替换为“\\”
- lua - 传递给 Pandoc 的变量可以在 lua 过滤器中使用吗?
- c# - C# 类对象列表更改以匹配最后一个对象?
- html - 高度/宽度为 100% 的 DIV 中的 iFrame
- kubernetes - 如何在 GKE 上为本地 SSD 磁盘获得更好的性能?
- azure - 如何让 Kudu 从我的仓库中删除一些文件夹?
- python - 如何在没有 PSUtil 的情况下使用 Python 2.7 获取总磁盘空间、已使用和可用磁盘空间
- bash - 在运行 Ubuntu 18 的桌面上进行一些处理后,BASH 脚本挂起,而在 Red Hat 服务器上工作正常
- java - osboot.SpringApplication : 应用程序运行失败
- server - Magento 2 网站每天宕机,需要重启服务器