将MIN和MAX合并到R中的行函数中

问题描述 投票:1回答:2

我在excel电子表格中使用了一些代码,这些代码使用了minmax,我正尝试将这些代码转移到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。

这是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"))
r max apply min
2个回答
1
投票

我们可以使用min计算在max范围内的5:19rowwise值的比率。

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

并且类似地在基数R中使用apply

df$ratio <- apply(df[-1], 1, function(x) mean(x[1]:x[2] %in% 5:19))

1
投票

这里是使用data.table的矢量化版本:

DT[, portion := {
    mn <- pmax(mini, lb)
    mx <- pmin(maxi, ub)
    fifelse(mn <= mx, (mx - mn + 1L) / (maxi - mini + 1L), 0)
}]

或等效于基数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
© www.soinside.com 2019 - 2024. All rights reserved.