R 查找数据帧的值,该值介于其他数据帧上两列的值之间

R 查找数据帧的值,该值介于其他数据帧上两列的值之间,r,R,我有两个数据帧。dataframe_A包含用户和给定值: dfA用户值 > 1 1 54 > 2 2 12 > 3 3 7 > 4 4 123 > 5 5 74 dfB包含值的范围和我想添加到dfA的乘数: 最小最大多重 > 1 0 50 0.0 > 2 50 80 0.5 > 3 80 100 0.8 > 4 100 120 1.0 > 5 120 1000 1.2 因此,理想的结果是将dfB中的乘数添加

我有两个数据帧。dataframe_A包含用户和给定值:

dfA用户值 > 1 1 54 > 2 2 12 > 3 3 7 > 4 4 123 > 5 5 74 dfB包含值的范围和我想添加到dfA的乘数:

最小最大多重 > 1 0 50 0.0 > 2 50 80 0.5 > 3 80 100 0.8 > 4 100 120 1.0 > 5 120 1000 1.2 因此,理想的结果是将dfB中的乘数添加到dfB中:

dfA 用户价值乘数 [1] 1 54 0.5 [2] 2 12 0 [3] 3 7 0 [4] 4 123 1.2 [5] 5 74 0.5 我已经尝试过使用单个值的代码,但在数据帧中不起作用:

dfA$Mult dfB$Min和dfA$Value 对于dfA中的每个值,都可以使用基本R中的sapply

资料

您可以对dfA中的每个值使用基本R中的sapply

资料

如果dfB中的区间通过将其按顺序区间分割(如示例中所示)形成更大范围的分区,我们还可以使用findInterval或cut将dfA中的值与dfB中的区间相匹配。使用findInterval:

findIntervalx=dfA$Value,vec=cdfB$Min[1],dfB$Max > [1] 2 1 1 5 2 结合在dfA中创建新的Mult列,我们可以编写:

dfA$Mult用户价值Mult > 1 1 54 0.5 > 2 2 12 0.0 > 3 3 7 0.0 > 4 4 123 1.2 > 5 5 74 0.5 免责声明:如果dfB中的间隔排列不整齐,则findInterval的使用会变得更加乏味,在这种情况下,Ronak的方法可能更简单。

如果dfB中的间隔通过按顺序间隔分割而形成更大范围的分区,如示例所示,我们还可以使用findInterval或cut将dfA中的值与dfB中的间隔相匹配。使用findInterval:

findIntervalx=dfA$Value,vec=cdfB$Min[1],dfB$Max > [1] 2 1 1 5 2 结合在dfA中创建新的Mult列,我们可以编写:

dfA$Mult用户价值Mult > 1 1 54 0.5 > 2 2 12 0.0 > 3 3 7 0.0 > 4 4 123 1.2 > 5 5 74 0.5
免责声明:如果dfB中的间隔没有很好地对齐,那么findInterval的使用将变得更加乏味,在这种情况下,Ronak的方法可能更简单。

一些tidyverse解决方案。前两个表在两个表之间进行交叉连接(这对于大型表来说可能非常昂贵),然后将结果过滤到每个原始dfA行一行,其中值在dfB范围内。最后一个肯定会更快,因为它会立即过滤dfB,每个值过滤一次,然后使用过滤和堆叠的mult定义新的dfA变量-但它会通过嵌套在另一个映射中的并行映射执行一些trippy操作,所有映射都在mutate中,所以我敢打赌,对于那些不太熟悉Purr的人来说,这很难理解。但我很想看到一些比较基准

还要注意的是,任务不清楚:Mult括号之间的边缘情况-如果值为50,Mult是0还是0.5?我和更高的骡子一起走

dfA=最小值,值<最大%>% 选择最小值,-最大值 >一个tibble:5x3 >用户价值乘数 > > 1 1 54 0.5 > 2 2 12 0 > 3 3 7 0 > 4 4 123 1.2 > 5 5 74 0.5 略显冗长,但略显枯燥 交叉DFA,dfB%>% 过滤器列表值,最小值,最大值-1%>%pmap\u LGL介于%>% 选择最小值,-最大值 >一个tibble:5x3 >用户价值乘数 > > 1 1 54 0.5 > 2 2 12 0 > 3 3 7 0 > 4 4 123 1.2 > 5 5 74 0.5 绝对更快,更干燥,更冗长,更难阅读 dfA%>%突变 Mult=值%>%map\U dbl ~dfB%>% 过滤器列表.x,最小值,最大值-1%>%pmap\u LGL介于%>% 普穆特 >用户价值乘数 > 1 1 54 0.5 > 2 2 12 0.0 > 3 3 7 0.0 > 4 4 123 1.2 > 5 5 74 0.5
2019年9月29日由v0.3.0版的一些tidyverse解决方案创建。前两个表在两个表之间进行交叉连接(这对于大型表来说可能非常昂贵),然后将结果过滤到每个原始dfA行一行,其中值在dfB范围内。最后一个肯定会更快,因为它会立即过滤dfB,每个值过滤一次,然后使用过滤和堆叠的mult定义新的dfA变量-但它会通过嵌套在另一个映射中的并行映射执行一些trippy操作,所有映射都在mutate中,所以我敢打赌,对于那些不太熟悉Purr的人来说,这很难理解。但我很想看到一些比较基准

还要注意的是,任务不清楚:Mult括号之间的边缘情况-如果值为50,Mult是0还是0.5?我和更高的骡子一起走

dfA=最小值,值<最大%>% 选择最小值,-最大值 >一个tibble:5x3 >用户价值乘数 > > 1 1 54 0.5 > 2 2 12 0 > 3 3 7 0 > 4 4 123 1.2 > 5 5 74 0.5 略显冗长,但略显枯燥 交叉DFA,dfB%>% 过滤器列表值,最小值,最大值-1%>%pmap\u LGL介于%>% 选择最小值,-最大值 >一个tibble:5x3 >用户价值乘数 > > 1 1 54 0.5 > 2 2 12 0 > 3 3 7 0 > 4 4 123 1.2 > 5 5 74 0.5 绝对更快,更干燥,更冗长,更难阅读 dfA%>%突变 Mult=值%>%map\U dbl ~dfB%>% 过滤器列表.x,最小值,最大值-1%>%pmap\u LGL介于%>% 普穆特 >用户价值乘数 > 1 1 54 0.5 > 2 2 12 0.0 > 3 3 7 0.0 > 4 4 123 1.2 > 5 5 74 0.5 由v0.3.0于2019-09-29创建,代码如下:

dfA <- structure(list(User = 1:5, Value = c(54L, 12L, 7L, 123L, 74L)), 
             row.names = c(NA, -5L), class = "data.frame")

dfB <- structure(list(Min = c(0L, 50L, 80L, 100L, 120L), Max = c(50L, 80L, 
             100L, 120L,1000L), Mult = c(0, 0.5, 0.8, 1, 1.2)), 
             class = "data.frame", row.names = c(NA, -5L))
# we add a mult column to dfA and set all its values to NA
dfA$mult = NA
# now we create a function which takes input as a single value from dfA
# and returns the desired multiplier from dfB
mult_fun = function(x)
{
  for (j in 1:nrow(dfB)) {
    if(x > dfB$Min[j] & x < dfB$Max[j]) {
      return(dfB$Mult[j])
    }
  }
}
# now we use mult_fun and gets multiplier for every value in dfA
for (i in 1:nrow(dfA)) {
  dfA$mult[i] = mult_fun(dfA$Value[i])
}
代码如下:

dfA <- structure(list(User = 1:5, Value = c(54L, 12L, 7L, 123L, 74L)), 
             row.names = c(NA, -5L), class = "data.frame")

dfB <- structure(list(Min = c(0L, 50L, 80L, 100L, 120L), Max = c(50L, 80L, 
             100L, 120L,1000L), Mult = c(0, 0.5, 0.8, 1, 1.2)), 
             class = "data.frame", row.names = c(NA, -5L))
# we add a mult column to dfA and set all its values to NA
dfA$mult = NA
# now we create a function which takes input as a single value from dfA
# and returns the desired multiplier from dfB
mult_fun = function(x)
{
  for (j in 1:nrow(dfB)) {
    if(x > dfB$Min[j] & x < dfB$Max[j]) {
      return(dfB$Mult[j])
    }
  }
}
# now we use mult_fun and gets multiplier for every value in dfA
for (i in 1:nrow(dfA)) {
  dfA$mult[i] = mult_fun(dfA$Value[i])
}

感谢您提供数据reprex,@Ronaksah。PietroAiorta,如果能在原始问题中包含这一点,那就太好了。谢谢你提供数据reprex,@RonakShah。PietroAiorta,如果能在原始问题中包含这一点就好了。50的理想Mult是多少?在我看来,最小值或最大值都应该减去1,或者,至少应该指定边缘情况是属于较低的括号还是较高的括号。对于50的值,所需的Mult是多少?在我看来,最小值或最大值都应该减去1,或者,至少应该指定边缘案例是属于较低的括号还是较高的括号。
dfA <- structure(list(User = 1:5, Value = c(54L, 12L, 7L, 123L, 74L)), 
             row.names = c(NA, -5L), class = "data.frame")

dfB <- structure(list(Min = c(0L, 50L, 80L, 100L, 120L), Max = c(50L, 80L, 
             100L, 120L,1000L), Mult = c(0, 0.5, 0.8, 1, 1.2)), 
             class = "data.frame", row.names = c(NA, -5L))
# we add a mult column to dfA and set all its values to NA
dfA$mult = NA
# now we create a function which takes input as a single value from dfA
# and returns the desired multiplier from dfB
mult_fun = function(x)
{
  for (j in 1:nrow(dfB)) {
    if(x > dfB$Min[j] & x < dfB$Max[j]) {
      return(dfB$Mult[j])
    }
  }
}
# now we use mult_fun and gets multiplier for every value in dfA
for (i in 1:nrow(dfA)) {
  dfA$mult[i] = mult_fun(dfA$Value[i])
}
> dfA
  User Value mult
1    1    54  0.5
2    2    12  0.0
3    3     7  0.0
4    4   123  1.2
5    5    74  0.5