【问题标题】:Overlap between two datasets两个数据集之间的重叠
【发布时间】:2019-08-15 10:59:22
【问题描述】:

我目前正在处理两组数据,这些数据提供 2013 年 2 月 2 日至 2018 年 9 月期间相同金融产品的月度价格。这两个数据集没有每个产品的每个月的价格,数据集 1 的数据比数据集 2 更准确。

我想找到一种方法来合并这两个数据集,以获得具有最准确数据的结果数据集(来自 Dataset1),并使用来自 Dataset 2 的可用数据完成此数据。

此外,我想知道两个数据集之间重叠的数据百分比。

假设这些是我的两个数据集的样本:

Dataset 1
 201602     201603     201604                 
1 103.5     102.4      101.6 
2 0         0          104.2              
3 101.6     101.7      102     

Dataset 2
 201602     201603     201604                 
1 0         103.1      102.8 
2 102.3     103.5      104.5              
3 0         101.5      102.3

我想获得:

Dataset 1
`201602`   `201603`   `201604`                 
1 103.5     102.4      101.6 
2 102.3     103.5      104.2              
3 101.6     101.7      102 

并且表明我的重叠 = 5/9 = 55.6%

我有超过 1000 种金融产品,所以我正在寻找最简单的代码。

提前感谢您的帮助!

【问题讨论】:

  • “重叠”是什么意思?它是如何计算的?
  • 您的两个数据集是否具有完全相同的行数和列数,对应相同的月份和产品? 0 的值是否表示缺失?
  • @MKBakker :我的数据集具有完全相同的行数和列数,对应于相同的月份和产品,是的。而0 的值确实表示缺失
  • @RonakShah 的“重叠”是指两个数据集中存在的数据的百分比,考虑到0 表示没有数据。例如,对于列201603,第 1 行和第 3 行的数据同时存在于两个数据集中,因此它们重叠。
  • @RonakShah 但是,“201602”列没有重叠。数据集 1 有第 1 行和第 3 行的数据,而数据集 2 没有,数据集 2 有第 2 行的数据,而数据集 1 没有

标签: r


【解决方案1】:

由于您希望优先考虑df1 而不是df2,我们可以将df1 的内容复制到df3,并将df1 的值替换为df2

df3 <- df1
df3[df3 == 0] <- df2[df3 == 0]

df3
#  201602 201603 201604
#1  103.5  102.4  101.6
#2  102.3  103.5  104.2
#3  101.6  101.7  102.0

为了计算重叠,我们可以比较两个数据中的非零值

mean((df1 != 0) == (df2 != 0)) * 100
#[1] 55.55555556

数据

df1 <- structure(list(`201602` = c(103.5, 0, 101.6), `201603` = c(102.4, 
0, 101.7), `201604` = c(101.6, 104.2, 102)), class = "data.frame", 
row.names = c("1", "2", "3"))

df2 <- structure(list(`201602` = c(0, 102.3, 0), `201603` = c(103.1, 
103.5, 101.5), `201604` = c(102.8, 104.5, 102.3)), class = "data.frame", 
row.names = c("1", "2", "3"))

【讨论】:

  • 第一部分看起来不错。但是,通过计算重叠,您现在正在计算 df1df2 的哪个字段都非零。不是这些非零值是否相等。为此,您可以这样做:mean((df1==df2) &amp; (df1!=0)) * 100。在您的示例数据中,该数据将为 0%(请检查,所有值都不同),但使用其他数据(例如提供的@Romain Berrou),它给出了重叠百分比。如果你解决了这个问题,那么请向我 +1。
  • @MKBakker 我同意,但 OP 对重叠的定义不同(与他们帖子下方的 cmets 不同)。 by "overlap" I mean the percentage of data that is present in both datasets, taking under account that 0 means no data 所以他们想知道 df1 和 df2 中非零字段的百分比,这就是您获得 55.6% 的预期输出的方式。如果我误解了什么,请告诉我。
  • 既然你这么说,我想这就是要求的定义。在那种情况下,你完全按照 OP 的要求做了!
  • @MKBakker 我认为根据您的公式,答案将是 11% (1/9),因为 103.5 存在于两个初始数据集中,不是吗?
  • 非常感谢大家! @RonakShah 的公式为我做到了,我现在有了另一个有用的公式来确定精确相似数据的百分比!
【解决方案2】:

在评论中,我提到使用 long 表格而不是 wide 表格通常总是一个好主意。在长表中,信息整齐:每一行是一个观察值,每一列是一个变量。虽然宽表更适合电子表格用户,但长表更容易通过使用严肃的分析工具来处理,例如 R

我将在整个答案中使用data.table 包,因为它非常快捷方便:

将您的数据转换为 data.tables 并添加一个 id 列

library(data.table)
setDT(df1)[, id := 1:.N]

setDT(df2)[, id := 1:.N]

将宽表转换为长表

longdf1 <- melt(df1, id.vars = "id")
longdf2 <- melt(df2, id.vars = "id")
# check what's in longdf1!

加入表格并创建新变量

## I'll do it first in two steps, but you can use chaining and do it straigth away:
# first join the tables:

joinedTable <- longdf1[longdf2, on = .(id, variable)]

# then create the variable:

joinedTable[, newValue := ifelse(value == 0, i.value, value)]

## Alternatively, you can do it in one run:

joinedTable <- longdf1[longdf2, on = .(id, variable)][, newValue := ifelse(value == 0, i.value, value)]

joinedTable 现在有了你想要的结果(虽然它是长格式)。

为什么长格式有用?尝试绘制它(这显然不是问题的一部分,但我认为是最相关的部分之一!):

library(ggplot2)
ggplot(longdf1, aes(x = id, y = value, color = variable))+geom_point()

或者尝试取平均值:

longdf1[, mean(value)]

(尝试在宽表上执行这两个操作,代码更长且令人费解)。一般来说,长表中的操作更容易执行。

转换回宽屏

也许您需要将数据恢复为宽格式,因此代码如下:

dcast(joinedTable[, .(id, variable, newValue)], id ~ variable)

使用的数据

df1 <- structure(list(`201602` = c(103.5, 0, 101.6), `201603` = c(102.4, 
0, 101.7), `201604` = c(101.6, 104.2, 102)), class = "data.frame", 
row.names = c("1", "2", "3"))

df2 <- structure(list(`201602` = c(0, 102.3, 0), `201603` = c(103.1, 
103.5, 101.5), `201604` = c(102.8, 104.5, 102.3)), class = "data.frame", 
row.names = c("1", "2", "3"))

编辑:我差点忘了“重叠”计算:

joinedTable[, sum(apply(.SD, 1, function(x) !any(x == 0)))/.N, .SDcols = c("value", "i.value")]
[1] 0.5555556

【讨论】:

  • 感谢您这么长的回答!我会尽快申请并回复您!
猜你喜欢
  • 2014-09-29
  • 2013-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多