【问题标题】:How to lookup for a single value in two different datasets that have two columns in common (based on a condition)如何在具有两列共同的两个不同数据集中查找单个值(基于条件)
【发布时间】:2021-01-22 18:17:13
【问题描述】:

我有两个不同的数据集,如下所示:

当且仅当:两个数据集中的 ID 和 Date 列都匹配时,我需要在数据集 #2 中添加 call volume、put volume 和 total volume 列。我根据数据集 #1 中第 3 列中的值(C 代表调用,P 代表看跌,T 代表总计)来区分看涨、看跌和总计。

我正在运行此代码,但它不起作用(仅显示调用示例,同样的规则适用于 put 和 totals)。

dataset2$call_volume <- if(dataset1$optiontype== "C")
{ dataset1$volume [ match (
                          interaction(dataset2$ID,dataset2$date),
                          interaction(dataset1$ID,dataset1$date)
                                         )]}

有没有人建议我如何继续编写代码?非常感谢!

> dput(dataset1)
structure(list(ID = c(44652, 44652, 44652, 56266, 56266, 56266, 
44652, 44652, 44652, 56266, 56266, 56266), date = c("1997/01/02", 
"1997/01/02", "1997/01/02", "1997/01/02", "1997/01/02", "1997/01/02", 
"1997/01/03", "1997/01/03", "1997/01/03", "1997/01/03", "1997/01/03", 
"1997/01/03"), `option type (C,P,T: for calls, puts, and total)` = c("C", 
"P", "T", "C", "P", "T", "C", "P", "T", "C", "P", "T"), volume = c(34, 
250, 284, 30, 0, 30, 1443, 211, 1654, 4490, 826, 5316)), row.names = c(NA, 
-12L), class = c("tbl_df", "tbl", "data.frame"))

> dput(dataset2)
structure(list(ID = c(44652, 44652, 44652, 56266, 56266, 56266
), date = c("1997/01/02", "1997/01/03", "1997/01/04", "1997/01/02", 
"1997/01/03", "1997/01/04"), `call volume` = c(NA, NA, NA, NA, 
NA, NA), `put volume` = c(NA, NA, NA, NA, NA, NA), `total volume` = c(NA, 
NA, NA, NA, NA, NA)), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

更新:我在两个数据集中还有许多其他列彼此完全不同,唯一常见的是下面图片和数据集中显示的列。

【问题讨论】:

  • 嗨,阿拉。您尚未向我们展示您的数据。您向我们展示了您的数据的图片。为了让任何人展示一个可行的解决方案,他们必须将图片转录成文本。您能否编辑您的问题(使用问题下方的灰色“编辑”链接)以包含这里的人们可以使用的数据?您可以在控制台中输入dput(dataset1)dput(dataset2),然后将结果粘贴到您的问题中。谢谢。
  • @AllanCameron 谢谢艾伦,完成。我希望它现在有效!

标签: r match lookup matching


【解决方案1】:

我认为这是一个 x/y 问题。我认为您实际上是在尝试将dataset1 转换为宽格式以填充dataset2。之后你可以left_join这两个框架。

library(tidyr)
library(dplyr)

names(dataset1)[3] <- "option_type"

dataset2 %>% 
  dplyr::select(-`call volume`, -`put volume`, -`total volume`) %>%
  left_join(dataset1 %>% 
  tidyr::pivot_wider(names_from = "option_type", values_from = "volume") %>%
  rename("Call Volume" = C, "Put Volume" = P, "Total Volume" = `T`),
  by = c("ID", "date"))
#> # A tibble: 6 x 5
#>      ID date       `Call Volume` `Put Volume` `Total Volume`
#>   <dbl> <chr>              <dbl>        <dbl>          <dbl>
#> 1 44652 1997/01/02            34          250            284
#> 2 44652 1997/01/03          1443          211           1654
#> 3 44652 1997/01/04            NA           NA             NA
#> 4 56266 1997/01/02            30            0             30
#> 5 56266 1997/01/03          4490          826           5316
#> 6 56266 1997/01/04            NA           NA             NA

reprex package (v0.3.0) 于 2020 年 10 月 7 日创建

【讨论】:

  • 谢谢@Allan Cameron。代码运行良好。但是,我在帖子中没有提到数据集 2 包含许多其他未与数据集 1 共享的列(反之亦然)。有没有办法通过保持这些列保持原样来做到这一点?谢谢
  • @AlaB 在这种情况下,您需要 left_join 宽格式 dataset1 到 dataset2 (删除空 NA 列之后)。请查看我的更新。
【解决方案2】:

如果我理解正确,如果匹配,您希望 dataset2 具有来自 dataset1 的值,如果不匹配,则需要 NA。

如果是这种情况,您需要使用left_join

如果没有,请使用所需的输出更新您的问题。

library(tidyverse)

d1 <- structure(list(ID = c(44652, 44652, 44652, 56266, 56266, 56266, 
                            44652, 44652, 44652, 56266, 56266, 56266), date = c("1997/01/02", 
                                                                                "1997/01/02", "1997/01/02", "1997/01/02", "1997/01/02", "1997/01/02", 
                                                                                "1997/01/03", "1997/01/03", "1997/01/03", "1997/01/03", "1997/01/03", 
                                                                                "1997/01/03"), `option type (C,P,T: for calls, puts, and total)` = c("C", 
                                                                                                                                                     "P", "T", "C", "P", "T", "C", "P", "T", "C", "P", "T"), volume = c(34, 
                                                                                                                                                                                                                        250, 284, 30, 0, 30, 1443, 211, 1654, 4490, 826, 5316)), row.names = c(NA, 
                                                                                                                                                                                                                                                                                               -12L), class = c("tbl_df", "tbl", "data.frame"))


d2 <- structure(list(ID = c(44652, 44652, 44652, 56266, 56266, 56266
), date = c("1997/01/02", "1997/01/03", "1997/01/04", "1997/01/02", 
            "1997/01/03", "1997/01/04"), `call volume` = c(NA, NA, NA, NA, 
                                                           NA, NA), `put volume` = c(NA, NA, NA, NA, NA, NA), `total volume` = c(NA, 
                                                                                                                                 NA, NA, NA, NA, NA)), row.names = c(NA, -6L), class = c("tbl_df", 
                                                                                                                                                                                         "tbl", "data.frame"))

d1_longer <- d1 %>%
  pivot_wider(names_from = `option type (C,P,T: for calls, puts, and total)`, values_from = volume) %>%
  rename(`call volume` = `C`, `put volume` = `P`, `total volume` = `T`)

d2 %>%
  select(ID, date) %>%
  left_join(d1_longer)
#> Joining, by = c("ID", "date")
#> # A tibble: 6 x 5
#>      ID date       `call volume` `put volume` `total volume`
#>   <dbl> <chr>              <dbl>        <dbl>          <dbl>
#> 1 44652 1997/01/02            34          250            284
#> 2 44652 1997/01/03          1443          211           1654
#> 3 44652 1997/01/04            NA           NA             NA
#> 4 56266 1997/01/02            30            0             30
#> 5 56266 1997/01/03          4490          826           5316
#> 6 56266 1997/01/04            NA           NA             NA

reprex package (v0.3.0) 于 2020 年 10 月 7 日创建

【讨论】:

  • 谢谢@Icaro Bombonato。这也很好用!糟糕的是,我没有提到我在数据集 1 和 2 中的其他列不在两者之间共享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 2022-11-14
  • 2018-05-07
相关资源
最近更新 更多