通过两列合并两个数据帧导致空白 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
让你做到这一点。
假设我们有 df1
和 df2
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
如您所见,z
和 w
完全匹配,所以我们知道我们做对了。
在您的数据中:
df1
= qtpo_liver_dates
df2
= labs_v500
date1
, date2
= liver_date
x
= patient_num
z
= qtpo_liver_dates
中的某列
w
= labs_v500
中的某列
我有一个肝移植患者及其手术日期的数据框 (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
让你做到这一点。
假设我们有 df1
和 df2
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
如您所见,z
和 w
完全匹配,所以我们知道我们做对了。
在您的数据中:
df1
= qtpo_liver_dates
df2
= labs_v500
date1
, date2
= liver_date
x
= patient_num
z
= qtpo_liver_dates
w
= labs_v500