按日期(年份和月份)合并数据框。

5

第一种情况

我有两个数据框,如下所示:

df1 = read.table(text = 'Date  ID
1980-12-01  2
1982-11-01  1
1990-01-01  6
1993-07-01  9', header = TRUE)

df2 = read.table(text = 'Date  Var
1980-12-17  8
1982-11-07  9
1990-01-19  10
1993-07-20  22', header = TRUE)

我需要按照“日期”列将df1与df2合并,但只考虑年份和月份,因为否则合并将无法进行(因为日期不同)。
我的输出应该像这样:
Date    ID  Var
1980-12  2    8
1982-11  1    9
1990-01  6   10
1993-07  9   22

我考虑删除日期列中的天数,但我想知道是否有更快速的方法。我也做了检查,似乎之前没有人问过这个问题。
谢谢。
更新:
第二种情况
如评论所建议的,如果在同一个数据框中有多个观测值在同一年和月份呢?
df1 = read.table(text = 'Date  ID #as 1st Case
1980-12-01  2
1982-11-01  1
1990-01-01  6
1993-07-01  9', header = TRUE)

df3 = read.table(text = 'Date  Var
    1980-12-17  8
    1980-12-29  4
    1980-12-30  1
    1982-11-07  9
    1982-11-12  1
    1990-01-19  10
    1990-01-22  21
    1993-07-20  22
    1993-07-26  12', header = TRUE)

我的新输出应该是:

Date   Var    ID
1980-12  8     2
1980-12  4     2
1980-12  1     2
1982-11  9     1
1982-11  1     1
1990-01  10    6
1990-01  21    6
1993-07  22    9
1993-07  12    9

更新

第三种情况

如果我的两个数据框中在相同的年份和月份下有多个观测值怎么办?

df4 = read.table(text = 'Date  ID 
    1980-12-01  1
    1980-12-01  2
    1982-11-01  3
    1982-11-01  4
    1990-01-01  5
    1990-01-01  6
    1993-07-01  7
    1993-07-01  8', header = TRUE)

df3 = read.table(text = 'Date  Var      #as 2nd Case
    1980-12-17  8
    1980-12-29  4
    1980-12-30  1
    1982-11-07  9
    1982-11-12  1
    1990-01-19  10
    1990-01-22  21
    1993-07-20  22
    1993-07-26  12', header = TRUE)

新的输出应该是:
    Date       Var  ID
    1980-12-17   8   1
    1980-12-17   8   2
    1980-12-29   4   1
    1980-12-29   4   2
    1980-12-30   1   1
    1980-12-30   1   2
    1982-11-07   9   3
    1982-11-07   9   4
    1982-11-12   1   3
    1982-11-12   1   4
    1990-01-19   10  5
    1990-01-19   10  6
    1990-01-22   21  5
    1990-01-22   21  6
    1993-07-20   22  7
    1993-07-20   22  8
    1993-07-26   12  7
    1993-07-26   12  8

1
首先,加一分因为提供可重现的数据和期望输出;) - Tensibai
1
如果您有同一月份的多个观察结果,该怎么办? - mtoto
我更新了我的问题。这实际上是我的最终目标。感谢您指出这一点。 - user7109363
2个回答

5

您需要将日期格式化为月份和年份格式,然后进行常规合并。

df1$my=format(as.Date(df1$Date), "%Y-%m")
df2$my=format(as.Date(df2$Date), "%Y-%m")
merge(df1,df2, by='my')

对于同一年份和月份的多个观测值,这个方法仍然适用。

df1$my=format(as.Date(df1$Date), "%Y-%m")
df3$my=format(as.Date(df3$Date), "%Y-%m")
merge(df1,df3, by='my')
      my     Date.x ID     Date.y Var
1 1980-12 1980-12-01  2 1980-12-17   8
2 1980-12 1980-12-01  2 1980-12-29   4
3 1980-12 1980-12-01  2 1980-12-30   1
4 1982-11 1982-11-01  1 1982-11-07   9
5 1982-11 1982-11-01  1 1982-11-12   1
6 1990-01 1990-01-01  6 1990-01-19  10
7 1990-01 1990-01-01  6 1990-01-22  21
8 1993-07 1993-07-01  9 1993-07-20  22
9 1993-07 1993-07-01  9 1993-07-26  12

对于更新3,可以使用

merge(df4,df3, by='my', all = T)

你是对的,页面没有更新,你发帖大约在20或30秒之前。 - akrun
1
感谢您的评论,很高兴知道您从我的帖子中获得了灵感。 - akrun
嗨@ChirayuChamoli,您可以看一下我的更新吗?这正是我真正需要做的。谢谢。 - user7109363
这是因为在df1中每个月只有单个观测值。 - mtoto

2
我们将日期转换为 Date 类型,将格式化为年月格式,并在数据集和 merge 中合并它们。
merge(transform(df1, Date = format(as.Date(Date), "%Y-%m")), 
             transform(df2, Date = format(as.Date(Date), "%Y-%m")))
#     Date ID Var
#1 1980-12  2   8
#2 1982-11  1   9
#3 1990-01  6  10
#4 1993-07  9  22

如果有多个数据集,将其放在一个列表中进行转换和合并。

Reduce(function(...) merge(...), 
    lapply(mget(paste0("df", 1:2)), transform, Date = format(as.Date(Date), "%Y-%m")))

嗨@akrun,你能看一下我的更新吗?否则我将被迫取消答案的接受。非常感谢。 - user7109363

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接