如何将分层范围扩展到数据框中的最大值之外?
How to extend the range of stratification beyond the maximum value in a data frame?
假设我们从以下数据框开始,其下方有生成代码:
> stratData
ID Period Values
1 1 2020-03 -5
2 1 2020-04 25
3 2 2020-01 35
4 2 2020-02 45
5 2 2020-03 55
6 2 2020-04 87
7 3 2020-02 10
8 3 2020-03 20
9 3 2020-04 30
stratData <-
data.frame(
ID = c(1,1,2,2,2,2,3,3,3),
Period = c("2020-03", "2020-04", "2020-01", "2020-02", "2020-03", "2020-04", "2020-02", "2020-03", "2020-04"),
Values = c(-5, 25, 35, 45, 55, 87, 10, 20, 30)
)
我有一个闪亮的应用程序,它允许用户根据不同的标准(包括分层带的大小)对数据框中的某些值进行分层。底部是分层 MWE 代码。我遇到的问题是分层范围没有正确标记范围内的最大值。如下所示,最大范围显示 NA,而不是正确的 (85,90] 以包含来自 stratData
数据框的最大值。如何解决这个问题?
# A tibble: 7 x 5
Range Count Values Count_pct Values_pct
<fct> <dbl> <dbl> <dbl> <dbl>
1 [25,35] 2 55 66.7 38.7
2 (35,45] 0 0 0 0
3 (45,55] 0 0 0 0
4 (55,65] 0 0 0 0
5 (65,75] 0 0 0 0
6 (75,85] 0 0 0 0
7 NA 1 87 33.3 61.3
这是生成上述内容的 MWE 代码 table(有来自更完整的 App 的遗迹;我考虑过制作 max = round(value, -1) 或类似的东西,但很困难用户是否能够输入不同的范围以自定义分层):
custom_min <- function(x) {if (length(x)>0) min(x, na.rm=TRUE) else Inf}
custom_max <- function(x) {if (length(x)>0) max(x, na.rm=TRUE) else Inf}
filter_exp1 <- parse(text=paste0("Period", "==", "'","2020-04", "'"))
stratData_1 <- stratData %>% filter(eval(filter_exp1))
min <- custom_min(stratData_1[[3]])
max <- custom_max(stratData_1[[3]])
breaks <- if(any(is.infinite(c(min,max)))) c(0, 10) else seq(min, max, by = 10) # < in full code, the 10 is a variable the user can change via Shiny
tmp <- stratData %>%
filter(eval(filter_exp1)) %>%
mutate(Range = cut(!!sym("Values"), breaks=breaks, include.lowest=TRUE, right = TRUE, dig.lab = 5)) %>%
group_by(Range) %>%
summarise(Count = n(),Values = sum(!!sym("Values"))) %>%
complete(Range, fill = list(Count = 0,Values = 0)) %>%
ungroup %>%
mutate(Count_pct = Count/sum(Count)*100, Values_pct = Values/sum(Values)*100) %>%
dplyr::select(everything(), Count, Count_pct, Values, Values_pct)
tmp
您需要使用例如seq(min, max, length.out = 5)
。这里不能使用by
参数,因为max=87
不是10的倍数:
min <- 25
max <- 87
# does not include the max
seq(min, max, by = 10)
#> [1] 25 35 45 55 65 75 85
# does include the max
seq(min, max, length.out = 5)
#> [1] 25.0 40.5 56.0 71.5 87.0
由 reprex package (v2.0.1)
创建于 2022-02-07
以上danlooo解决方案暂时在大App中使用。 Danlooo 解决方案允许用户在 seq()
函数中使用 length.out =
而不是 by =
来指定分层中的波段数。但是,随着应用程序的发展,我可能会更改它以允许用户指定最小波段值、最大波段值和波段厚度。 (需要评估这种增加的复杂性是否值得)。为了允许用户指定带厚度并添加另一个带以包含每个 OP 的最大数据框值,您可以 add/change OP MWE 中的以下内容:
# New line:
tmpSeq <- seq(min, max, by = 10)
# Replace "breaks" in OP with the following using the append() function:
breaks <- if(any(is.infinite(c(min,max)))) c(0, 10) else append(tmpSeq,tmpSeq[length(tmpSeq)]+10)
假设我们从以下数据框开始,其下方有生成代码:
> stratData
ID Period Values
1 1 2020-03 -5
2 1 2020-04 25
3 2 2020-01 35
4 2 2020-02 45
5 2 2020-03 55
6 2 2020-04 87
7 3 2020-02 10
8 3 2020-03 20
9 3 2020-04 30
stratData <-
data.frame(
ID = c(1,1,2,2,2,2,3,3,3),
Period = c("2020-03", "2020-04", "2020-01", "2020-02", "2020-03", "2020-04", "2020-02", "2020-03", "2020-04"),
Values = c(-5, 25, 35, 45, 55, 87, 10, 20, 30)
)
我有一个闪亮的应用程序,它允许用户根据不同的标准(包括分层带的大小)对数据框中的某些值进行分层。底部是分层 MWE 代码。我遇到的问题是分层范围没有正确标记范围内的最大值。如下所示,最大范围显示 NA,而不是正确的 (85,90] 以包含来自 stratData
数据框的最大值。如何解决这个问题?
# A tibble: 7 x 5
Range Count Values Count_pct Values_pct
<fct> <dbl> <dbl> <dbl> <dbl>
1 [25,35] 2 55 66.7 38.7
2 (35,45] 0 0 0 0
3 (45,55] 0 0 0 0
4 (55,65] 0 0 0 0
5 (65,75] 0 0 0 0
6 (75,85] 0 0 0 0
7 NA 1 87 33.3 61.3
这是生成上述内容的 MWE 代码 table(有来自更完整的 App 的遗迹;我考虑过制作 max = round(value, -1) 或类似的东西,但很困难用户是否能够输入不同的范围以自定义分层):
custom_min <- function(x) {if (length(x)>0) min(x, na.rm=TRUE) else Inf}
custom_max <- function(x) {if (length(x)>0) max(x, na.rm=TRUE) else Inf}
filter_exp1 <- parse(text=paste0("Period", "==", "'","2020-04", "'"))
stratData_1 <- stratData %>% filter(eval(filter_exp1))
min <- custom_min(stratData_1[[3]])
max <- custom_max(stratData_1[[3]])
breaks <- if(any(is.infinite(c(min,max)))) c(0, 10) else seq(min, max, by = 10) # < in full code, the 10 is a variable the user can change via Shiny
tmp <- stratData %>%
filter(eval(filter_exp1)) %>%
mutate(Range = cut(!!sym("Values"), breaks=breaks, include.lowest=TRUE, right = TRUE, dig.lab = 5)) %>%
group_by(Range) %>%
summarise(Count = n(),Values = sum(!!sym("Values"))) %>%
complete(Range, fill = list(Count = 0,Values = 0)) %>%
ungroup %>%
mutate(Count_pct = Count/sum(Count)*100, Values_pct = Values/sum(Values)*100) %>%
dplyr::select(everything(), Count, Count_pct, Values, Values_pct)
tmp
您需要使用例如seq(min, max, length.out = 5)
。这里不能使用by
参数,因为max=87
不是10的倍数:
min <- 25
max <- 87
# does not include the max
seq(min, max, by = 10)
#> [1] 25 35 45 55 65 75 85
# does include the max
seq(min, max, length.out = 5)
#> [1] 25.0 40.5 56.0 71.5 87.0
由 reprex package (v2.0.1)
创建于 2022-02-07以上danlooo解决方案暂时在大App中使用。 Danlooo 解决方案允许用户在 seq()
函数中使用 length.out =
而不是 by =
来指定分层中的波段数。但是,随着应用程序的发展,我可能会更改它以允许用户指定最小波段值、最大波段值和波段厚度。 (需要评估这种增加的复杂性是否值得)。为了允许用户指定带厚度并添加另一个带以包含每个 OP 的最大数据框值,您可以 add/change OP MWE 中的以下内容:
# New line:
tmpSeq <- seq(min, max, by = 10)
# Replace "breaks" in OP with the following using the append() function:
breaks <- if(any(is.infinite(c(min,max)))) c(0, 10) else append(tmpSeq,tmpSeq[length(tmpSeq)]+10)