我有两个 data.frames 如下:
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)
Run Code Online (Sandbox Code Playgroud)
我需要按日期列将 df1 与 df2 合并,但仅考虑年份和月份,还因为否则合并不起作用(因为日期不同)。
我的输出应该是这样的:
Date ID Var
1980-12 2 8
1982-11 1 9
1990-01 6 10
1993-07 9 22
Run Code Online (Sandbox Code Playgroud)
我考虑删除日期列中的天数,但我想知道是否有更快的方法来执行此操作。我也查了一下,好像没有人问过这个问题。
谢谢
#更新
正如评论中所建议的,如果我在一个 data.frame 中的同一年和同一月有多个观察结果怎么办?
例如
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)
Run Code Online (Sandbox Code Playgroud)
我的新输出应该是:
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
Run Code Online (Sandbox Code Playgroud)
#
更新
如果我在同一年和同一月的两个 data.frames 中都有多个观察值怎么办?
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)
Run Code Online (Sandbox Code Playgroud)
新的输出应该是:
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
Run Code Online (Sandbox Code Playgroud)
您需要将日期格式化为月和年格式。然后你进行常规合并。
df1$my=format(as.Date(df1$Date), "%Y-%m")
df2$my=format(as.Date(df2$Date), "%Y-%m")
merge(df1,df2, by='my')
Run Code Online (Sandbox Code Playgroud)
对于同一年同月的多次观察,这仍然有效。
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
Run Code Online (Sandbox Code Playgroud)
对于更新 3,可以使用
merge(df4,df3, by='my', all = T)
Run Code Online (Sandbox Code Playgroud)
我们将数据集中的“日期”转换为Date类、format年月格式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
Run Code Online (Sandbox Code Playgroud)
或者如果有很多数据集,将其放入 a 中list并进行转换和合并
Reduce(function(...) merge(...),
lapply(mget(paste0("df", 1:2)), transform, Date = format(as.Date(Date), "%Y-%m")))
Run Code Online (Sandbox Code Playgroud)