【问题标题】:Calculating distance between 2 elements of a data frame计算数据框的 2 个元素之间的距离
【发布时间】:2019-02-07 03:56:51
【问题描述】:

我有一个如下所示的数据框:

library(dplyr)
size_df <- tibble(size_chr = c("XS", "S", "M", "L", "XL", "1XL", "2XL", "3XL", "4XL", "5XL", "6XL"),
                  size_min = c(0,36,39,42,45,48,52,56,60,64,66),
                  size_max = c(36,39,42,45,48,52,56,60,64,66,70))

对于任何小于 70 的给定数字,我想找到它之间的两个尺寸,以及它们之间的距离(标准化为 0 和 1 之间)

例如:

input <- 37.2

# S  0.6
# M   0.4

input <- 48

# XL  1

input <- 68

# 5XL  0.5
# 6XL   0.5

【问题讨论】:

  • 37.2 不在 XS 的范围内?
  • 哎呀,你说得对,谢谢。已编辑

标签: r dplyr


【解决方案1】:

这是findInterval() 的完美案例。我们将创建类别之间的间隔向量,并使用它们来计算比例因子。

size_breaks <- c(size_df[["size_min"]], max(size_df[["size_max"]]))
size_breaks
# [1]  0 36 39 42 45 48 52 56 60 64 66 70
size_spans  <- diff(size_breaks)
size_scales <- 1 / size_spans
size_scales
# [1] 0.02777778 0.33333333 0.33333333 0.33333333 0.33333333 0.25000000 0.25000000
# [8] 0.25000000 0.25000000 0.50000000 0.25000000

findInterval() 将为我们提供下限的索引。上限就是那个索引 + 1。

neighbor_distances <- function(x) {
  lower <- findInterval(x, size_breaks)
  neighbors <- c(lower, lower + 1)
  distances <- abs(x - size_breaks[neighbors]) * size_scales[lower]
  tibble(
    size_chr = size_df[["size_chr"]][neighbors],
    distance = distances
  )
}

它适用于您的第一个示例。

neighbor_distances(37.2)
# # A tibble: 2 x 2
#   size_chr distance
#   <chr>       <dbl>
# 1 S           0.4  
# 2 M           0.600

第二个例子给出了两行而不是仅仅一行,但这可以通过函数中的额外逻辑来处理。为了简单起见,我忽略了这个逻辑。

neighbor_distances(48)
# # A tibble: 2 x 2
#   size_chr distance
#   <chr>       <dbl>
# 1 1XL             0
# 2 2XL             1

它为您的第三个示例提供了不同的答案,但我不知道您为什么希望将一个数字与小于下限的尺寸类别进行比较。

neighbor_distances(68)
# # A tibble: 2 x 2
#   size_chr distance
#   <chr>       <dbl>
# 1 6XL           0.5
# 2 NA            0.5

【讨论】:

    【解决方案2】:
    INDS = c(max(1, tail(which(size_df$size_min < input), 1)),
      min(NROW(size_df), 1 + head(which(size_df$size_max > input), 1)))
    size_df$size_chr[INDS]
    #[1] "S" "M"
    
    DIST = c(abs(size_df$size_min[INDS[1]] - input),
             abs(size_df$size_max[INDS[2]] - input))
    DIST/sum(DIST)
    #[1] 0.2 0.8
    

    【讨论】:

      猜你喜欢
      • 2020-02-06
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 2010-09-26
      • 2016-06-15
      相关资源
      最近更新 更多