r - 如何在日期之间合并
问题描述
我有 2 个如下所示的数据框:
df1
ID Drugname Startdate Enddate Dose
<dbl> <chr> <date> <date> <chr>
1 111xxx LAMISIL CREME 10MG/G 2008-04-04 2008-04-12 2. DA
2 111xxx LAMISIL CREME 10MG/G 2009-07-05 2009-07-12 2. AB
3 111xxx LAMISIL CREME 5MG/G 2009-11-22 2009-12-05 2. AB
4 111xxx TERBINAFINE TABL 250MG 2009-07-06 2009-08-11 1.1T
5 111xxx CLOZAPINE TABL 25MG 2005-06-01 2005-06-28 N 2T
6 111xxx CLOZAPINE TABL 25MG 2005-07-01 2005-07-28 N 2T
7 222xxx MAGNESIUM HYD KAUWT 724MG 2000-04-11 2000-04-24 1.1T
8 222xxx MAGNESIUM HYD KAUWT 724MG 2012-03-17 2012-03-25 1.1T
etc.
df2
ID (...) DATE_RESULT v1 v2
1: 111xxx 2007-11-28 <NA> 165
2: 111xxx 2009-07-08 <NA> 105
3: 222xxx 2009-08-24 <NA> 125
4: 222xxx 2012-03-27 66 20
etc.
我想合并df1
并df2
看起来像这样:
ID (...) DATE_RESULT v1 v2 Drugname1 Drugname2 NearDrug
1: 111xxx 2007-11-28 <NA> 165 NA NA NA
2: 111xxx 2009-07-08 <NA> 105 LAMISIL TERBINAFINE NA
3: 222xxx 2009-08-24 <NA> 125 NA NA NA
4: 222xxx 2012-03-27 66 20 NA NA MAGNESIUM
etc.
我ID
只想DATE_RESULT
在df2
介于Startdate
和Enddate
之间时合并这些df1
。由于ID
s 可以有多个Drugname
s,我希望它们彼此合并在同一行中,如新 df 的第 2 行所示。
然后我想要另一个合并/列(我不知道这是否可能),我ID
只想在inDATE_RESULT
之后df2
最多 7 天时合并,创建列,如新 df 的第 4 行所示。Enddate
df1
Neardrug
对于第一个问题,我已经尝试过:r merge by id and date between two dates,但这并没有给我我想要的新数据框,而且我太菜鸟了,无法更改该代码。
我想保留所有数据df2
而不是df1
. 由于显而易见的原因,所有信息都已被更改。
解决方案
那好吧!让我们将您的问题分为两部分。第一部分是按日期执行所述连接,第二部分是将许多结果分布在列上,而不是行上。
第 1 部分
虽然data.table
可以解决问题,但我建议使用sqldf
which 允许您使用 SQL 语法,如果您想更改逻辑条件或使其更复杂,该语法更具可读性、直观性和可扩展性。
library(data.table)
library(sqldf)
setDT(df1)
setDT(df2)
result <- sqldf("
select
df2.*,
df1.Drugname,
case
when df1.ID is null then NULL
when df2.DATE_RESULT between df1.Startdate and df1.Enddate then 'Drugname'
else 'Neardrug'
end as situation
from df2
left join df1
on df1.ID = df2.id
and df2.DATE_RESULT between df1.Startdate and date(df1.Enddate, '+7 days')
")
print(result)
ID DATE_RESULT v1 v2 Drugname situation
1 111xxx 2007-11-28 NA 165 <NA> <NA>
2 111xxx 2009-07-08 NA 105 LAMISIL CREME 10MG/G Drugname
3 111xxx 2009-07-08 NA 105 TERBINAFINE TABL 250MG Drugname
4 222xxx 2009-08-24 NA 125 <NA> <NA>
5 222xxx 2012-03-27 66 20 MAGNESIUM HYD KAUWT 724MG Neardrug
如您所见,查询已经返回一个名为 的列situation
,它可以是“Drugname”或“Neardrug”。
第 2 部分
现在您希望将同一 ID 的多行结果展开成列。理想的格式是将它们保持原样,在行和列的数据框中,没有重复的列。这被称为tidy
格式,它通常被 R 中的几个库用作标准,具有几个优点。
因此,我们可以将列宽格式视为打印输出的格式,以使其更具可读性。还有其他担忧。如果您的栏目过多且内容过长,则可能会变得难以管理。但是,让我们去做吧。
为了做到这一点,我们首先需要将“药物名称”的情况创建为“药物名称1”、“药物名称2”等的序列名称。“Neardrug”->“Neardrug1”、“Neardrug2”等也是如此。
library(dplyr)
sequenced_result <- result %>%
arrange(ID, DATE_RESULT, situation, Drugname) %>%
group_by(ID, situation) %>%
mutate(sequencing = row_number()) %>%
mutate(colname = ifelse(is.na(situation), "Drugname1", paste0(situation, sequencing))) %>%
ungroup()
print(sequenced_result)
ID DATE_RESULT v1 v2 Drugname situation sequencing colname
<chr> <chr> <dbl> <dbl> <chr> <chr> <int> <chr>
1 111xxx 2007-11-28 NA 165 NA NA 1 Drugname1
2 111xxx 2009-07-08 NA 105 LAMISIL CREME 10MG/G Drugname 1 Drugname1
3 111xxx 2009-07-08 NA 105 TERBINAFINE TABL 250MG Drugname 2 Drugname2
4 222xxx 2009-08-24 NA 125 NA NA 1 Drugname1
5 222xxx 2012-03-27 66 20 MAGNESIUM HYD KAUWT 724MG Neardrug 1 Neardrug1
我们快到了。现在我们需要做的就是通过执行枢轴操作将行值移动到列上。
library(tidyr)
formatted_result <- sequenced_result %>%
select(-c(situation, sequencing)) %>%
pivot_wider(names_from = colname, values_from = Drugname)
print(formatted_result)
# A tibble: 4 x 7
ID DATE_RESULT v1 v2 Drugname1 Drugname2 Neardrug1
<chr> <chr> <dbl> <dbl> <chr> <chr> <chr>
1 111xxx 2007-11-28 NA 165 NA NA NA
2 111xxx 2009-07-08 NA 105 LAMISIL CREME 10MG/G TERBINAFINE TABL 250MG NA
3 222xxx 2009-08-24 NA 125 NA NA NA
4 222xxx 2012-03-27 66 20 NA NA MAGNESIUM HYD KAUWT 724~
作为画龙点睛的一笔,如果您愿意,您可以只显示每个药物名称的第一个单词。
library(stringr)
formatted_result_short <- sequenced_result %>%
select(-c(situation, sequencing)) %>%
mutate(Drugname = word(Drugname)) %>%
pivot_wider(names_from = colname, values_from = Drugname)
print(formatted_result_short)
ID DATE_RESULT v1 v2 Drugname1 Drugname2 Neardrug1
<chr> <chr> <dbl> <dbl> <chr> <chr> <chr>
1 111xxx 2007-11-28 NA 165 NA NA NA
2 111xxx 2009-07-08 NA 105 LAMISIL TERBINAFINE NA
3 222xxx 2009-08-24 NA 125 NA NA NA
4 222xxx 2012-03-27 66 20 NA NA MAGNESIUM
推荐阅读
- codeigniter - 如何从 codeigniter 中的模块语言文件加载 Cor 库中的语言文件
- c++ - ifstream 没有明显的原因不读取文件
- hyperledger-fabric - 如何将当前运行的生产级别 Hyperledger 1.4v 更新到 v2.0.1
- javascript - 在 JavaScript 中生成唯一的订单号(人类可读)
- javascript - React-Admin DateField,DateInput locale global
- html - 可重用组件中的 AnyChart 未出现在正确的 DOM 位置(Angular 9.1.3、Bootstrap 4.4.1、Anychart 8.7.1)
- excel - 应用程序.评估(“<
>") 抛出应用程序定义的错误 - perl - 使用一个变量作为布尔值来检查它是否已被设置很好,但是 undef 呢?
- ffmpeg - ffmpeg avformat_open_input() 无法打开包含中文字符的 dshow 设备 url
- oracle - Toad 12.9 连接到 Oracle 18c 时出错