将 MIN 和 MAX 组合成 R 中的 rowise 函数
Combining MIN and MAX into a rowise function in R
我在 excel 电子表格中使用了一些代码,该电子表格使用了 min
和 max
,我正试图将其转移到 R。
我有两列,"mini"
和 "maxi"
代表一系列可能的值。我要填充的第三列是该范围内介于 5 和 19 之间的比例。查看示例中的第一行,如果 "mini"
为 10 且 "maxi"
为 15,则该值5-19 列的 应为 1,因为范围完全落在该跨度内。在第 9 行中,"mini"
是 1,"maxi"
是 3,这意味着它完全落在 5-19 范围之外,因此应该是 0。然而,第 3 行跨越了这个范围,并且只有25%落在5-19的范围内,所以输出值应该是0.25。
编辑 我已经更新了 R,虽然之前有几个解决方案有效,但我现在收到错误:
Error in mutate_impl(.data, dots, caller_env()) :
attempt to bind a variable to R_UnboundValue
这是 DF 外观的示例:
ID mini maxi
1 10 15
2 17 20
3 2 5
4 40 59
5 40 59
6 21 39
7 21 39
8 17 20
9 1 3
10 4 6
我之前使用的代码是这样的:
=MAX((MIN(maxi,19)-MAX(mini,5)+1),0)/(maxi-mini+1)
我最初尝试使用
percentoutput <- mutate(DF, output = MAX((MIN(maxi,19) - MAX(mini,5) + 1),0)/(maxi-mini + 1))
这导致 ouput
列充满了 NA。
我不确定在这种情况下我是否需要 运行 一个 apply
函数,但我不确定如何设置它。任何指导表示赞赏!
这是一个例子DF:
structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), min = c(10,
17, 2, 40, 40, 21, 21, 17, 1, 4), max = c(15, 20, 5, 59, 59,
39, 39, 20, 3, 6)), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -10L), spec = structure(list(
cols = list(ID = structure(list(), class = c("collector_double",
"collector")), mini = structure(list(), class = c("collector_double",
"collector")), maxi = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
我们可以使用 rowwise
计算 min
与 max
值的比率,这些值在 5:19
范围内。
library(dplyr)
df %>% rowwise() %>% mutate(ratio = mean(min:max %in% 5:19))
# ID min max ratio
# <dbl> <dbl> <dbl> <dbl>
# 1 1 10 15 1
# 2 2 17 20 0.75
# 3 3 2 5 0.25
# 4 4 40 59 0
# 5 5 40 59 0
# 6 6 21 39 0
# 7 7 21 39 0
# 8 8 17 20 0.75
# 9 9 1 3 0
#10 10 4 6 0.667
同样在 base R 中使用 apply
:
df$ratio <- apply(df[-1], 1, function(x) mean(x[1]:x[2] %in% 5:19))
这是一个矢量化版本,使用 data.table
:
DT[, portion := {
mn <- pmax(mini, lb)
mx <- pmin(maxi, ub)
fifelse(mn <= mx, (mx - mn + 1L) / (maxi - mini + 1L), 0)
}]
或等同于 base R:
DF$mn <- pmax(DF$mini, lb)
DF$mx <- pmin(DF$maxi, ub)
DF$portion <- ifelse(DF$mn <= DF$mx, (DF$mx - DF$mn + 1L) / (DF$maxi - DF$mini + 1L), 0)
输出:
ID mini maxi portion
1: 1 10 15 1.0000000
2: 2 17 20 0.7500000
3: 3 2 5 0.2500000
4: 4 40 59 0.0000000
5: 5 40 59 0.0000000
6: 6 21 39 0.0000000
7: 7 21 39 0.0000000
8: 8 17 20 0.7500000
9: 9 1 3 0.0000000
10: 10 4 6 0.6666667
数据:
library(data.table)
DT <- fread("ID mini maxi
1 10 15
2 17 20
3 2 5
4 40 59
5 40 59
6 21 39
7 21 39
8 17 20
9 1 3
10 4 6")
lb <- 5L
ub <- 19L
我们可以使用map2
library(dplyr)
library(purrr)
df %>%
mutate(ratio = map2_dbl(min, max, ~ mean(.x:.y %in% 5:19)))
我在 excel 电子表格中使用了一些代码,该电子表格使用了 min
和 max
,我正试图将其转移到 R。
我有两列,"mini"
和 "maxi"
代表一系列可能的值。我要填充的第三列是该范围内介于 5 和 19 之间的比例。查看示例中的第一行,如果 "mini"
为 10 且 "maxi"
为 15,则该值5-19 列的 应为 1,因为范围完全落在该跨度内。在第 9 行中,"mini"
是 1,"maxi"
是 3,这意味着它完全落在 5-19 范围之外,因此应该是 0。然而,第 3 行跨越了这个范围,并且只有25%落在5-19的范围内,所以输出值应该是0.25。
编辑 我已经更新了 R,虽然之前有几个解决方案有效,但我现在收到错误:
Error in mutate_impl(.data, dots, caller_env()) :
attempt to bind a variable to R_UnboundValue
这是 DF 外观的示例:
ID mini maxi
1 10 15
2 17 20
3 2 5
4 40 59
5 40 59
6 21 39
7 21 39
8 17 20
9 1 3
10 4 6
我之前使用的代码是这样的:
=MAX((MIN(maxi,19)-MAX(mini,5)+1),0)/(maxi-mini+1)
我最初尝试使用
percentoutput <- mutate(DF, output = MAX((MIN(maxi,19) - MAX(mini,5) + 1),0)/(maxi-mini + 1))
这导致 ouput
列充满了 NA。
我不确定在这种情况下我是否需要 运行 一个 apply
函数,但我不确定如何设置它。任何指导表示赞赏!
这是一个例子DF:
structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), min = c(10,
17, 2, 40, 40, 21, 21, 17, 1, 4), max = c(15, 20, 5, 59, 59,
39, 39, 20, 3, 6)), class = c("spec_tbl_df", "tbl_df", "tbl",
"data.frame"), row.names = c(NA, -10L), spec = structure(list(
cols = list(ID = structure(list(), class = c("collector_double",
"collector")), mini = structure(list(), class = c("collector_double",
"collector")), maxi = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
我们可以使用 rowwise
计算 min
与 max
值的比率,这些值在 5:19
范围内。
library(dplyr)
df %>% rowwise() %>% mutate(ratio = mean(min:max %in% 5:19))
# ID min max ratio
# <dbl> <dbl> <dbl> <dbl>
# 1 1 10 15 1
# 2 2 17 20 0.75
# 3 3 2 5 0.25
# 4 4 40 59 0
# 5 5 40 59 0
# 6 6 21 39 0
# 7 7 21 39 0
# 8 8 17 20 0.75
# 9 9 1 3 0
#10 10 4 6 0.667
同样在 base R 中使用 apply
:
df$ratio <- apply(df[-1], 1, function(x) mean(x[1]:x[2] %in% 5:19))
这是一个矢量化版本,使用 data.table
:
DT[, portion := {
mn <- pmax(mini, lb)
mx <- pmin(maxi, ub)
fifelse(mn <= mx, (mx - mn + 1L) / (maxi - mini + 1L), 0)
}]
或等同于 base R:
DF$mn <- pmax(DF$mini, lb)
DF$mx <- pmin(DF$maxi, ub)
DF$portion <- ifelse(DF$mn <= DF$mx, (DF$mx - DF$mn + 1L) / (DF$maxi - DF$mini + 1L), 0)
输出:
ID mini maxi portion
1: 1 10 15 1.0000000
2: 2 17 20 0.7500000
3: 3 2 5 0.2500000
4: 4 40 59 0.0000000
5: 5 40 59 0.0000000
6: 6 21 39 0.0000000
7: 7 21 39 0.0000000
8: 8 17 20 0.7500000
9: 9 1 3 0.0000000
10: 10 4 6 0.6666667
数据:
library(data.table)
DT <- fread("ID mini maxi
1 10 15
2 17 20
3 2 5
4 40 59
5 40 59
6 21 39
7 21 39
8 17 20
9 1 3
10 4 6")
lb <- 5L
ub <- 19L
我们可以使用map2
library(dplyr)
library(purrr)
df %>%
mutate(ratio = map2_dbl(min, max, ~ mean(.x:.y %in% 5:19)))