通过两列合并两个数据帧导致空白 df

Merging two dataframes by two columns resulting in blank df

我有一个肝移植患者及其手术日期的数据框 (qtpo_liver_dates)。在此数据框中,每个患者都有自己的手术日期。同一队列的另一个数据框 (labs_v500) 显示实验室日期和结果,以及包括手术日期在内的访问日期,但大多数日期不感兴趣。我想在 R 中合并患者和手术日期的数据框(即按实际手术日期过滤 labs_v500)。我尝试了以下但返回了一个空白数据框

df <- merge(qtpo_liver_dates,labs_v500, by = c("patient_num","liver_date"))

有人可以解释一下最好的方法吗?

当您在此处 post 提问时,最好以易于使用的方式包含一些示例数据。除了图片,您还可以 dput(head(my_data_frame) 获取您可以在问题中 post 的数据样本。由于您没有这样做,我创建了一小部分数据来说明解决方案。

这是我为模拟您的问题而创建的相同数据:

qtpo_liver_dates <- data.frame(
  patient_num = c(1, 2, 3),
  liver_date = c("2007-08-01", "2004-10-05", "2014-03-09")
)

labs_v500 <- data.frame(
  patient_num = c(1, 2, 3),
  liver_date = c("8/1/2007", "10/5/2004", "3/9/2014"),
  other_data = c("Other Data A", "Other Data B", "Other Data C")
)

正如@jdobres 提到的,merge() 不起作用,因为 liver_date 的格式在两个数据集中有所不同。但是,使用 lubridate 包中的函数很容易纠正这个问题。

我们将通过两次调用 lubridate 函数来更正日期格式。首先,我们将使用 mdy(),它需要 month-day-year 格式的数据。在第二个中,我们将使用 ymd() 查找 year-month-day 格式的数据。在这两种情况下,我们都会用新的日期变量替换数据框 liver_date 变量中的字符串。

library(lubridate)

qtpo_liver_dates$liver_date <- ymd(qtpo_liver_dates$liver_date)
labs_v500$liver_date <- mdy(labs_v500$liver_date)

现在 merge() 应该可以工作了,并且由于两个数据帧之间的公共变量名称相同,因此无需明确指定它们。

merge(qtpo_liver_dates, labs_v500)

输出:

  patient_num liver_date   other_data
1           1 2007-08-01 Other Data A
2           2 2004-10-05 Other Data B
3           3 2014-03-09 Other Data C

您应该首先告诉 R liver_date 两列都是日期。函数 as.Date 让你做到这一点。

假设我们有 df1df2

date1<-(c("2007-08-01", "2004-10-05", "2014-03-09"))#Year - Month - Day
date2<-(c("8/1/07", "10/5/04", "3/9/14"))#Month/Day/Year 
x<-(c(1:3))
z<-c(11:13)
w<-c(11:13)


df1<-data.frame(date1, x, z)
str(df1$data1)
  
df1

> df1
       date1 x  z
1 2007-08-01 1 11
2 2004-10-05 2 12
3 2014-03-09 3 13

df2<-data.frame(date2, x, w)
str(df2$date2)

df2 
> df2
    date2 x  w
1  8/1/07 1 11
2 10/5/04 2 12
3  3/9/14 3 13

使用 as.Date 可以告诉日期所在列的格式,因为 df1 是 Y-M-D

df1$date1<-as.Date.character(df1$date1,format="%Y-%m-%d")
str(df1$date1)

df2 是 m/d/y

df2$date1<-as.Date.character(df2$date2,format="%m/%d/%y")
str(df2$date1)

我们重新编码 df2$date1 中的 df2$date2 以匹配列的名称,稍后 merge 函数将需要它,在您的情况下,您可以重新编码列,因为它们具有相同的名称:

df3<-merge(df1,df2, by =c("date1", "x" ) )
df3

>df3
       date1 x  z   date2  w
1 2004-10-05 2 12 10/5/04 12
2 2007-08-01 1 11  8/1/07 11
3 2014-03-09 3 13  3/9/14 13

如您所见,zw 完全匹配,所以我们知道我们做对了。

在您的数据中:

df1 = qtpo_liver_dates

df2 = labs_v500

date1, date2 = liver_date

x = patient_num

z = qtpo_liver_dates

中的某列

w = labs_v500

中的某列