dplyr:根据不同条件分组,然后返回top n
Posted
技术标签:
【中文标题】dplyr:根据不同条件分组,然后返回top n【英文标题】:Dplyr: Group by and then return top n based on different conditons 【发布时间】:2021-11-15 16:49:23 【问题描述】:我一直在尝试解决对我的数据进行分组(按贷款编号)的问题,然后根据某一列(这里是过滤器列)的最高或最低值返回每组一行不同的条件。我意识到我不能使用 ifelse 来做我想做的事情,但是其他示例使用了 if 和 else(因此我尝试了)。在此过程中,我遇到了各种各样的错误。任何帮助以及澄清问题将不胜感激
Example data
Loan_Number <- c(100,100,100,100,200,200,200,200,300,300,300,300)
Principal_Remaining <- c(50,50,50,50,5,5,0,0,10,10,10,10)
Principal_In_Arrears <- c(50,50,50,50,0,0,0,0,0,10,10,10)
Write_off_Number <- c(10,10,10,10, 0,0,0,0,0,0,0,0)
Filter <- c (1,2,3,4,5,6,7,8,9,10,11,12)
outcome <- as.data.frame(cbind(Loan_Number,Principal_In_Arrears, Principal_Remaining, Write_off_Number, Filter))
我对代码的最后一次尝试是
hope <- outcome %>%
group_by(Loan_Number) %>%
if(Principal_Remaining == 0) top_n( -1, wt = Filter) else
if(Principal_In_Arrears == 0) top_n( -1, wt = Filter) else
if(Write_off_Number >= 0) top_n( 1, wt = Filter) else top_n( -1, wt =
Filter)))
这个想法是,如果没有本金,那么我想要一个特定的价值,如果有本金,我必须检查贷款是否拖欠或已注销。
NB 为了确认确切的要求,我需要避免考虑不符合条件的行。例如,对于贷款 200,返回的记录应返回第 7 行(本金为 0 的最低月份)。第一个答案没有这样做。此外,贷款 300 应该返回第 10 行(条件应该是!= 0 和过滤器的最小值),它在第一个月拖欠。贷款 1 应该只返回第 1 行。
【问题讨论】:
我有点不确定你想要的结果是什么。你能用伪代码写出你想要的条件,和/或提供一些预期的输出吗? 下面提供的答案是要发生的事情。 我在这里造成了一些混乱,抱歉。为了澄清事情,我改变了最初的 DF。 Loan 300 现在拖欠了创纪录的 10 笔。我实际上需要最小值,所以它现在应该返回第 10 行以获得贷款 300。 【参考方案1】:您可以使用case_when
和slice
来选择每个Loan_Number
的行。
library(dplyr)
outcome %>%
group_by(Loan_Number) %>%
slice(case_when(any(Principal_Remaining == 0) ~ which.max(Filter),
any(Principal_In_Arrears == 0) ~ which.min(Filter),
any(Write_off_Number >= 0) ~ which.max(Filter),
TRUE ~ which.min(Filter))) %>%
ungroup
# Loan_Number Principal_In_Arrears Principal_Remaining Write_off_Number Filter
# <dbl> <dbl> <dbl> <dbl> <dbl>
#1 100 50 50 10 4
#2 200 0 0 0 8
#3 300 10 10 0 12
【讨论】:
这个答案很接近但不太正确。我已经对原始问题进行了一些调整,以解释应该发生什么【参考方案2】:在这一点上这是可行的,但我不是 100% 它会随着其他组合的发展而继续发挥作用
hope <- outcome %>%
group_by(Banjo_Loan_No) %>%
dplyr::slice(case_when(any(Principal_Remaining == 0) ~ which.min(abs(filter*Principal_Remaining)),
any(Principal_in_Arrears == 0) ~ which.max(abs(filter*Principal_in_Arrears > 0)),
any(Write_Off_Date != "1016-01-01") ~ which.max(filter),
TRUE ~ which.min(filter)))
【讨论】:
以上是关于dplyr:根据不同条件分组,然后返回top n的主要内容,如果未能解决你的问题,请参考以下文章
R语言dplyr包的top_n函数返回dataframe或tibble的前N行数据dplyr包的top_frac函数返回dataframe或tibble的前百分之N(N%)的数据