假设我们有这样的数据框:
PatientID BookingID Level1 Level2 Value
a1 101-A1 1 HBA1C 9.4
a2 102-A2 1 LDL 116
a1 101-A1 1 VLDL 11
a1 101-A1 2 POL 10
a1 102-A1 1 HBA1c 9.4
a2 102-A2 1 VLDL 10
a1 102-A1 1 VLDL 11
a2 103-A2 1 LDL 116
a2 103-A2 1 VLDL 11
a1 102-A1 2 POL 10
这个想法是,患者(唯一患者ID)可以来实验室并接受一系列条件的测试 - 更广泛的测试类别 level1 ,他们的子类别 level2 < / strong>(level1与level2有一对多的关系),现在患者ID的 BookingId 列可能因访问的不同日期而异。 值列表示每项测试的值(患者ID与BookingID有一对多的关系)。
我想要一个输出:
PatientID BookingID Level1 Level2 Value
a1 101-A1 1 HBA1C 9.4
a2 102-A2 1 LDL 116
a1 101-A1 1 VLDL 11
a1 101-A1 2 POL 10
a2 102-A2 1 VLDL 10
a2 103-A2 1 LDL 116
a2 103-A2 1 VLDL 11
我们基本上想要删除重复项,如果某项 - level1 测试,如果患者自己测试两次并且值保持相同,在上面的示例中 - 对于患者ID-a2,尽管具有相同的level1测试的值,只有VLDL值(最后一行输出 - 与第三个最后一个值不同)不同,因此a2保持不变,而a1的单独实例被删除。
现在假设这是一个非常大的数据集,我们必须对每个level1测试及其对应特定患者的值进行比较。
我试过了:final2 <- final1 %>% group_by(level1, patientId, value) %>% slice(1)
但显然它不会工作,并将删除一些不必要的行,因为它不是按照逻辑执行。请帮忙
答案 0 :(得分:0)
final <- as.data.frame(sapply(final, toupper)) # consolidate case
final[!duplicated(dplyr::select(final, -BookingID), fromLast = T),]
PatientID BookingID Level1 Level2 Value
A1 102-A1 1 HBA1C 9.4
A2 102-A2 1 VLDL 10
A1 102-A1 1 VLDL 11
A2 103-A2 1 LDL 116
A2 103-A2 1 VLDL 11
A1 102-A1 2 POL 10
答案 1 :(得分:0)
(小心)考虑以下......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
( test_id INT NOT NULL
, patient_id INT NOT NULL
,category_id INT NOT NULL
,value DECIMAL(6,2) NOT NULL
);
INSERT INTO my_table VALUES
( 1,1,101,9.4),
( 2,2,102,116),
( 3,1,103, 11),
( 4,1,104, 10),
( 5,1,101,9.4),
( 6,2,105, 10),
( 7,1,105, 11),
( 8,2,106,116),
( 9,2,105, 11),
(10,1,104, 10);
SELECT * FROM my_table;
+---------+------------+-------------+--------+
| test_id | patient_id | category_id | value |
+---------+------------+-------------+--------+
| 1 | 1 | 101 | 9.40 |
| 2 | 2 | 102 | 116.00 |
| 3 | 1 | 103 | 11.00 |
| 4 | 1 | 104 | 10.00 |
| 5 | 1 | 101 | 9.40 |
| 6 | 2 | 105 | 10.00 |
| 7 | 1 | 105 | 11.00 |
| 8 | 2 | 106 | 116.00 |
| 9 | 2 | 105 | 11.00 |
| 10 | 1 | 104 | 10.00 |
+---------+------------+-------------+--------+
查询:
SELECT a.*
FROM my_table a
JOIN
( SELECT MAX(test_id) test_id FROM my_table GROUP BY patient_id,category_id,value) b
ON b.test_id = a.test_id
ORDER
BY test_id;
+---------+------------+-------------+--------+
| test_id | patient_id | category_id | value |
+---------+------------+-------------+--------+
| 2 | 2 | 102 | 116.00 |
| 3 | 1 | 103 | 11.00 |
| 5 | 1 | 101 | 9.40 |
| 6 | 2 | 105 | 10.00 |
| 7 | 1 | 105 | 11.00 |
| 8 | 2 | 106 | 116.00 |
| 9 | 2 | 105 | 11.00 |
| 10 | 1 | 104 | 10.00 |
+---------+------------+-------------+--------+
顺便提一下,&#39; booking_id&#39;可以即时生成,像这样......
SELECT a.test_id
, a.patient_id
, a.category_id
, a.value
, a.booking_id
FROM
( SELECT x.*
, CONCAT_WS('-',x.patient_id,LPAD(CASE WHEN @prev = patient_id THEN @i:=@i+1 ELSE @i:=1 END,3,0)) booking_id
, @prev:=patient_id
FROM my_table x
,
( SELECT @prev:=null,@i:=0) vars
ORDER
BY patient_id
, test_id
) a
ORDER
BY test_id;
+---------+------------+-------------+--------+------------+
| test_id | patient_id | category_id | value | booking_id |
+---------+------------+-------------+--------+------------+
| 1 | 1 | 101 | 9.40 | 1-001 |
| 2 | 2 | 102 | 116.00 | 2-001 |
| 3 | 1 | 103 | 11.00 | 1-002 |
| 4 | 1 | 104 | 10.00 | 1-003 |
| 5 | 1 | 101 | 9.40 | 1-004 |
| 6 | 2 | 105 | 10.00 | 2-002 |
| 7 | 1 | 105 | 11.00 | 1-005 |
| 8 | 2 | 106 | 116.00 | 2-003 |
| 9 | 2 | 105 | 11.00 | 2-004 |
| 10 | 1 | 104 | 10.00 | 1-006 |
+---------+------------+-------------+--------+------------+