R 如何在数据框中找到与特定标准匹配的最低值并返回特定列

R 如何在数据框中找到与特定标准匹配的最低值并返回特定列,r,R,首先,我对R很陌生,我也不熟悉问SO问题,所以如果我问了愚蠢的问题或者没有遵循SO惯例,请容忍我 我正试图根据多个用户以前的呼叫行为,为他们找到最佳的订阅类型。到目前为止,我已设法将大约98000行匹配起来,以计算(可变)订阅类型数量的有效成本 还有一个数据框,其中包含每个月每种订阅类型的预测成本: 现在,我正试图找到最好的订阅类型,每个用户和每个月的成本都低于当前的订阅类型。我将进行合并以显示我期望的结果: 因此,在2019-01月subscription\u 2的成本低于User1的当

首先,我对R很陌生,我也不熟悉问SO问题,所以如果我问了愚蠢的问题或者没有遵循SO惯例,请容忍我

我正试图根据多个用户以前的呼叫行为,为他们找到最佳的订阅类型。到目前为止,我已设法将大约98000行匹配起来,以计算(可变)订阅类型数量的有效成本

还有一个数据框,其中包含每个月每种订阅类型的预测成本:

现在,我正试图找到最好的订阅类型,每个用户和每个月的成本都低于当前的订阅类型。我将进行合并以显示我期望的结果:

因此,在2019-01月
subscription\u 2
的成本低于
User1
的当前订阅成本,因此应推荐
subscription2
。对于
2019-02
2019-03
月份,没有推荐,因为没有成本更低的订阅类型

对于
User2
subscription类型
subscription\u 3
应是所有月份的建议,因为这些成本始终低于当前订阅

我目前正在学习DataCamp.com上的课程,我非常确定这几乎肯定是
r
中的一个非常基本的操作,但我需要有人指导我正确的方向

这就是我到目前为止所做的:

library(dplyr)

effective.costs <- data.frame(
  user = c(rep("User1", 3), rep("User2", 3)),
  month = c(rep(c("2019-01", "2019-02", "2019-03"), 2)),
  current_subscription = c(rep("subscription_1", 3), rep("subscription_2", 3)),
  costs = c(70, 20, 50, 150, 130, 170)
)

predicted.costs <- data.frame(
  user = c(rep("User1", 9), rep("User2", 9)),
  month = c(rep("2019-01",3), rep("2019-02", 3), rep("2019-03", 3)),
  subscription = c(rep(c("subscription_1", "subscription_2", "subscription_3"), 6)),
  calculated_costs = c(
    c(70, 50, 110, 20, 50, 70, 50, 80, 120), 
    c(190, 150, 110, 210, 130, 110, 250, 170, 110)
    )
)

comparison <- merge(effective.costs, predicted.costs, by = c("user", "month"))

getRecommendation <- function(x) {
  subscription <- predicted.costs %>% 
    filter(
      calculated_costs < x['costs'] & 
      user == x['user'] & 
      month == x['month']
    ) %>%
    arrange(calculated_costs) %>%
    select(subscription) 
  subscription <- ifelse(
    length(subscription) > 0, 
    as.character(subscription[1, 1]), 
    NA
  )
  # I know return is not needed, but I'm used to it... :-)
  return(subscription)
}

effective.costs$recommendation <- apply(effective.costs, 1, getRecommendation)

View(effective.costs)

我正试图将其应用于
中的每一行
有效。成本

effective.costs$recommendation <- apply(effective.costs, 1, getRecommendation)

有效。成本$recommendation这取消了
apply
getRecommendation
功能
R
是矢量化的,因此我们应该尽可能多地考虑列

comparison <- merge(effective.costs, predicted.costs, by = c("user", "month"))

comparison%>%
  mutate(net_savings = calculated_costs-costs)%>%
  group_by(user, month)%>%
  filter(net_savings == min(net_savings))%>%
  slice(1) #for ties
比较%
突变(净节约=计算成本-成本)%>%
分组依据(用户,月份)%>%
过滤器(净节省==最小值(净节省))%>%
切片(1)#用于扎带
apply()
函数的问题是
apply()
将data.frame强制为矩阵。一个矩阵只能有一种类类型-在本例中,您正在将一个数字与
computed_costs
中的字符串进行比较

具体来说,评估是
计算的\u成本<'50'
,其中有一个额外的2位数空间。无论出于何种原因,
50<'70'
评估
FALSE
110<'190'
评估
TRUE


在这种情况下,解决方法是以不同的方式处理问题。无需通过
apply
执行行操作

抱歉,但我以为我就是这么做的?代码的前几行正在创建“虚拟”数据,如屏幕截图所示。。。你还希望我做什么?;-)对不起,伙计,我不知道我怎么会错过那个!:)@马丁-见下面的编辑。函数不起作用,因为
apply
将所有内容强制为一个字符。这使得数字比较困难。非常感谢你的解决方案和对我失败原因的解释!!!既然你提到了这一点,我还记得在华盛顿的课程中听到过这一点。。。你能解释一下最后的
slice(1)
是什么意思吗?它的意思是给我第一行。在这种情况下,因为我有group_by,这意味着给我每个组的第一行。这是为了防止关系出现,并与您的
as.character(订阅[1,1])
语句对齐。啊,我想我现在明白了。我原以为这会被
过滤器(净节省==min(净节省))
所覆盖,但是
切片(1)
适用于两个推荐订阅,费用相同,这会给我一个重复的行,对吗?谢谢!对如果两个处方具有相同的成本,则该用户月份将返回多行。编辑:你可能会去掉我的净成本,直接看成本。我把它弄得比需要的复杂。
comparison <- merge(effective.costs, predicted.costs, by = c("user", "month"))

comparison%>%
  mutate(net_savings = calculated_costs-costs)%>%
  group_by(user, month)%>%
  filter(net_savings == min(net_savings))%>%
  slice(1) #for ties