首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >连接数据帧,并在有多个匹配时选择随机行。

连接数据帧,并在有多个匹配时选择随机行。
EN

Stack Overflow用户
提问于 2019-06-12 10:06:18
回答 3查看 961关注 0票数 3

我有一个参考数据框架(df1),包含三列“特性”(性别、年份、代码)和两列“值”(数量、状态)。它看起来像这样,但是有很多行:

代码语言:javascript
运行
复制
gender    year    code    amount   status
     M    2011       A        15      EMX
     M    2011       A       123      NOX
     F    2015       B         0      MIX
     F    2018       A        12      NOX
     F    2015       B        11      NOX

我有另一个数据框架(df2),它只有三个“特性”列。例如:

代码语言:javascript
运行
复制
gender    year   code
     M    2011      A
     M    2011      A
     F    2018      A
     F    2015      B

对于df2中的每一行,我想根据“特征”中的匹配将“值”赋给df1。在有多个匹配的地方,我想随机选择“值”对。因此,当df2中存在重复的“特性”时,它们可能会以不同的“值”对结束,但它们在df1中都将完全匹配。本质上,对于每个特征组合,我希望值的分布在两个表之间匹配。

例如,'df2‘中的最后一行(性别= F,年份=2015年,代码= B)匹配’df1‘中的两行:第三行(amont = 0,status = MIX)和第五行( and = 11,status = NOX)。然后,应随机选择这些匹配行之一。对于基于性别、年份和代码的“df2”和“df1”之间的多个匹配情况,应该选择一个随机行。

到目前为止,我的方法是从使用dplyr在两个数据帧之间执行left_join开始。但是,这为df2中的每一行提供了所有可能的“值”,而不是随机选择一个。因此,我必须根据特征进行分组,并选择一个。这会产生一个非常大的中间表,而且看起来效率不高。

我想知道是否有人有更有效的方法的建议?我以前发现加入data.table包会更快,但是对这个包没有很好的理解。我还想知道我是应该做联接呢,还是应该只使用sample函数?

任何帮助都很感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-06-12 12:31:51

使用“d2”根据“性别”、“年份”、“代码”(d1[d2, on = .(gender, year, code), ...])中的匹配查找“d1”中的行。对于每个匹配(by = .EACHI),示例一行(sample(.N, 1L))。用这个来索引“金额”和“状态”。

代码语言:javascript
运行
复制
d1[d2, on = .(gender, year, code),
  {ri <- sample(.N, 1L)
  .(amount = amount[ri], status = status[ri])}, by = .EACHI]

# sample based on set.seed(1)
#    gender year code amount status
# 1:      M 2011    A     15    EMX
# 2:      M 2011    A     15    EMX
# 3:      F 2018    A     12    NOX
# 4:      F 2015    B     11    NOX

请注意,论据上有一个悬而未决的问题,即当x中的多行与i中的行匹配时,如何处理情况。目前,有效的选项是"all" (默认)、"first""last"。但是,如果/当问题实现时,可以使用mult = "random" (sample(.N, size = 1L))在匹配中选择随机行(行)。

票数 6
EN

Stack Overflow用户

发布于 2019-06-12 11:58:01

代码语言:javascript
运行
复制
df2 %>%
  mutate(
    amount = pmap_chr(
      .l = df2,
      .f = ~ df1 %>%
        filter(gender == ..1, year == ..2, code == ..3) %>%
        select(amount) %>%
        sample_n(1) %>%
        pull(amount)
    ),
    status = pmap_chr(
      .l = df2,
      .f = ~ df1 %>%
        filter(gender == ..1, year == ..2, code == ..3) %>%
        select(status) %>%
        sample_n(1) %>%
        pull(status)
    )
  )

这是相当缓慢的,我个人会避免它,但这是一种方法。

票数 1
EN

Stack Overflow用户

发布于 2019-06-12 11:58:26

我希望这样做是有效率的:

代码语言:javascript
运行
复制
df1[, row := .I]
keys <- c("year", "gender", "code")
setkeyv(df1, keys)
setkeyv(df2, keys)

for (rowdf2 in seq_len(nrow(df2))) {
  set(df2, i = rowdf2, j = "rowindf1", value = df1[df2[rowdf2], x.row[sample(.N, 1)]])
}

setkeyv(df1, "row")
df1[df2[, .(rowindf1)]]

示例输出:

代码语言:javascript
运行
复制
#    gender year code amount status row
# 1:      M 2011    A    123    NOX   2
# 2:      M 2011    A     15    EMX   1
# 3:      F 2015    B     11    NOX   5
# 4:      F 2018    A     12    NOX   4
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56559559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档