r - 在接近度上匹配两个 R 数据帧

标签 r distance

我有以下两个数据框:

df1 <- data.frame(group = rep("A", 5),
                  name = c("Brandon",
                           "Kyler",
                           "Trent",
                           "Lesa",
                           "Michael"),
                  gender = c("M", "F", "M", "F", "M"),
                  days = c(50, 45, 32, 60, 48))

df2 <- data.frame(group = rep("B", 10),
                  name = c("Erica", 
                           "Jared",
                           "Sara",
                           "Helen",
                           "Tom",
                           "Ron",
                           "Cy",
                           "Lynn",
                           "Ken",
                           "Judy"),
                  gender = c("F", "M", "F", "F", "M", "M", "M", "F", "M", "F"),
                  days = c(47, 49, 62, 80, 74, 30, 55, 58, 63, 25))

我想根据 gender 过滤 df2 以仅包含与 df1 数据框中的每一行最接近的匹配项天,优先考虑性别

例如,在 df1 中,“Brandon”有 gender == Mdays == 50。当我们只查看 df2 中的 gender == M 时,我们看到“Jared”在天数上最接近“Brandon”,因此“Jared”将被选为“布兰登”比赛。总的来说,生成的数据框如下所示:

# group  name gender days
#     B Jared      M   49
#     B Erica      F   47
#     B   Ron      M   30
#     B  Lynn      F   58
#     B    Cy      M   55

附加规则:

  • 这是一个分层合并,其中 gender 匹配优先于 days 接近度。

  • 请注意,df1 中有两个等距选项可匹配“Lesa”(“Sara”和“Lynn”)。随机选择两者之一来匹配“Lesa”。在上面的最终数据框中,示例选择了“Lynn”。

  • df2 中的“Jared”与 df1 中的“Brandon”和“Michael”距离相等。因为“Jared”已经匹配到“Brandon”,所以他不能再匹配到“Michael”。因此,与“Michael”的比赛继续进行到“Cy”,这是在 genderdays 方面的下一个最佳剩余比赛。

最佳答案

数据

首先,我将 stringsAsFactors = FALSE 添加到您的输入数据框中,因为在我的解决方案中使用字符串比使用因子更容易。

df1 <- data.frame(group = rep("A", 5),
              name = c("Brandon",
                       "Kyler",
                       "Trent",
                       "Lesa",
                       "Michael"),
              gender = c("M", "F", "M", "F", "M"),
              days = c(50, 45, 32, 60, 48),
              stringsAsFactors = FALSE)

df2 <- data.frame(group = rep("B", 10),
                  name = c("Erica", 
                           "Jared",
                           "Sara",
                           "Helen",
                           "Tom",
                           "Ron",
                           "Cy",
                           "Lynn",
                           "Ken",
                           "Judy"),
                  gender = c("F", "M", "F", "F", "M", "M", "M", "F", "M", "F"),
                  days = c(47, 49, 62, 80, 74, 30, 55, 58, 63, 25),
                  stringsAsFactors = FALSE)

解决方案

library(tidyverse)

# empty dataframe for the output
df2_new <- data.frame(group = character(),
                      name = character(),
                      gender = character(),
                      days = numeric(),
                      stringsAsFactors = FALSE)

for(i in 1:nrow(df1)){

  # add the row of interest to the output dataframe
  df2_new[i,] <- df2 %>% 
    mutate(day_diff = abs(days - df1$days[i])) %>%
    filter(gender == df1$gender[i]) %>% 
    slice(which.min(day_diff)) %>%
    select(-day_diff)

  # remove the newly added row from the original dataset
  df2 <- df2 %>%
    filter(!(name %in% df2_new$name))

}

这是第一个想到的解决方案。在这种情况下,随着 for 循环的进行,行从 df2 中删除,正如您所说的那样

want to filter df2 to include only the closest match to each row in the df1

输出

df2_new

  group  name gender days
1     B Jared      M   49
2     B Erica      F   47
3     B   Ron      M   30
4     B  Sara      F   62
5     B    Cy      M   55

在我的例子中,代码选择了 Sara 而不是 Lynn,但这是一个 50/50 的选择。

关于r - 在接近度上匹配两个 R 数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54220797/

相关文章:

r - 如何在 R 中创建一个计算唯一值的新列

mysql - 将度数转换为其他测量单位

algorithm - 在 3D 中搜索点之间的 K 个最小距离

javascript - 2 点之间的距离

python - 如何聚类多元角度数据?距离测量和算法

r - R 中 data.frame 内的矩阵或其他嵌套结构

将 NA 替换为数据框列表中列中的最大值

r - `pivot_longer` 操作 - 实现预期输出的更简单方法?

R包 "scholar"/获取文章的引用历史

r - 计算 R 中数据帧每一列中的非空值