您的大部分问题是由数据框的 untidy 特性引起的。我开始根据您不整洁的数据和整洁的等价物提供解决方案,但不整洁的解决方案虽然可能,但变得太痛苦了。
所以,这是一个基于与您的数据框相当的解决方案的解决方案。
首先,整理一下。您的数据框不整洁的原因是您的列名包含信息,即A1 和A2 包含A 中值的接受限制,等等。我们可以通过延长数据框来纠正这个问题。
由于原件的凌乱程度,这个过程有点长。或许可以使用names_pattern 和pivot_longer() 的其他高级参数来创建更紧凑的转换版本,但长版本至少有清晰的好处。
longDF <- df %>%
select(Number, Category, A, B, C) %>%
pivot_longer(
c(-Category, -Number),
names_to="Variable",
values_to="Value"
) %>%
left_join(
df %>%
select(Number, Category, A1, B1, C1) %>%
pivot_longer(
c(-Category, -Number),
names_to="Variable",
values_to="Lower"
) %>%
mutate(Variable=str_sub(Variable, 1, 1)),
by=c("Number", "Category", "Variable")
) %>%
left_join(
df %>%
select(Number, Category, A2, B2, C2) %>%
pivot_longer(
c(-Category, -Number),
names_to="Variable",
values_to="Upper"
) %>%
mutate(Variable=str_sub(Variable, 1, 1)),
by=c("Number", "Category", "Variable")
)
longDF
# A tibble: 6 x 6
Number Category Variable Value Lower Upper
<dbl> <dbl> <chr> <dbl> <dbl> <dbl>
1 1 1 A 5 10 30
2 1 1 B 10 5 15
3 1 1 C NA NA NA
4 2 2 A 40 10 30
5 2 2 B 20 5 15
6 2 2 C 45 25 35
因此,此时,我们的列定义了测试的Category、正在测量的Variable、其Value 和两个接受限制(Lower 和Upper)。
现在,确定每个 Value 的可接受性很简单。
longDF <- longDF %>%
mutate(
Result=ifelse(
Value < Lower,
"Pass",
ifelse(Value < Upper, "Danger", "Fail")
)
)
longDF
# A tibble: 6 x 7
Number Category Variable Value Lower Upper Result
<dbl> <dbl> <chr> <dbl> <dbl> <dbl> <chr>
1 1 1 A 5 10 30 Pass
2 1 1 B 10 5 15 Danger
3 1 1 C NA NA NA NA
4 2 2 A 40 10 30 Fail
5 2 2 B 20 5 15 Fail
6 2 2 C 45 25 35 Fail
另外,请注意每个值的分类独立于Variable 和可能变量的数量。所以代码在这些方面是健壮的。
现在我们可以按Number 和Category 对结果进行分类。
longDF %>%
group_by(Number, Category, Result) %>%
summarise(N=n(), .groups="drop") %>%
pivot_wider(
names_from=Result,
values_from=N,
values_fill=0
)
# A tibble: 2 x 7
Number Category Danger Pass `NA` Fail
<dbl> <dbl> <int> <int> <int> <int>
1 1 1 1 1 1 0
2 2 2 0 0 0 3
同样,我们在 Categorys 和 Numbers 的数量及其标签方面都很稳健。
评估整体结果也很简单,但由于选项繁多,因此有些冗长。请注意,您的文本与所需的输出不一致,因为您没有解释如何获得 "warn" for Category = 1 的整体结果。我和文字一起去了。如果您想匹配示例输出,一旦定义了标准,对代码的更改应该很简单。
longDF %>%
group_by(Number, Category, Result) %>%
summarise(N=n(), .groups="drop") %>%
pivot_wider(
names_from=Result,
values_from=N,
values_fill=0
) %>%
mutate(
Result=ifelse(
Category == 1,
ifelse(Fail == 0, "Pass", ifelse(Fail == 1, "Risk", "Fail")),
ifelse(Fail < 2, "Pass", ifelse(Fail == 2, "Risk", "Fail"))
)
)
# A tibble: 2 x 7
Number Category Danger Pass `NA` Fail Result
<dbl> <dbl> <int> <int> <int> <int> <chr>
1 1 1 1 1 1 0 Pass
2 2 2 0 0 0 3 Fail
如果您需要知道是哪个Variable 导致了潜在故障,也可以从longDF 获得,只需对分组稍作更改即可。
longDF %>%
group_by(Category, Variable, Result) %>%
summarise(N=n(), .groups="drop") %>%
pivot_wider(
names_from=Variable,
values_from=Result
)
# A tibble: 2 x 5
Category N A B C
<dbl> <int> <chr> <chr> <chr>
1 1 1 Pass Danger NA
2 2 1 Fail Fail Fail
当然,您可以将这两个数据框连接在一起,以获得对整体结果和组件变量评估的全面描述。