两个数据集之间的重叠

时间:2019-08-15 10:59:22

标签: r

我目前正在处理两组数据,这些数据提供02/2013至09/2018之间相同金融产品的每月价格。这两个数据集并没有每个产品的每月价格,数据集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多种金融产品,因此我正在寻找最简单的代码。

预先感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

由于您想将df1优先于df2,因此我们可以将df1的内容复制到df3并替换df1的值为0的值他们与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"))

答案 1 :(得分:1)

在评论中,我提到使用 long 表而不是 wide 表通常是一个好主意。在长表中,信息是 tidy :每一行都是观察值,每一列都是变量。宽表对电子表格用户来说更好,而长表则可以通过使用诸如 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