如何删除R中由三列组成的组中的重复项
假设我们有这样一个数据帧:如何删除R中由三列组成的组中的重复项,r,dataframe,dplyr,unique,R,Dataframe,Dplyr,Unique,假设我们有这样一个数据帧: 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
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
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
library(dplyr)
library(stringr)
library(tidyr)
df %>%
group_by(PatientID, BookingID) %>%
mutate(Key = paste(Level1, Level2, Value, collapse=";")) %>%
ungroup() %>%
select(-Level1, -Level2, -Value) %>%
distinct(PatientID, Key, .keep_all=TRUE) %>%
mutate(Key = str_split(Key, ";")) %>%
unnest(Key) %>%
separate(Key, into=c("Level1", "Level2", "Value"),
sep=" ", remove=TRUE) %>%
arrange(PatientID, BookingID, Level1, Level2)
# A tibble: 7 × 5
PatientID BookingID Level1 Level2 Value
* <chr> <chr> <chr> <chr> <chr>
1 a1 101-A1 1 HBA1C 9.4
2 a1 101-A1 1 VLDL 11
3 a1 101-A1 2 POL 10
4 a2 102-A2 1 LDL 116
5 a2 102-A2 1 VLDL 10
6 a2 103-A2 1 LDL 116
7 a2 103-A2 1 VLDL 11
其想法是,患者(唯一的患者ID)可以来到实验室并接受一组条件的测试-更广泛的测试类别是level1,其子类别是level2(level1与level2有一对多关系),现在患者ID的BookingId列可以根据不同的就诊日期而有所不同。值列表示每个测试的值(患者ID与BookingID具有一对多关系)
因此,一组由“级别1”、“patientID”及其“值”的一个组合组成,如果patientIDa1两次来测试自己——101-a1和102-a1,并且如果所有测试值都相同,则只剩下其中一个,如果有任何变化,如patientIDa2的情况,则所有值都保留,因此,我们希望o/p如下所示:
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
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
library(dplyr)
library(stringr)
library(tidyr)
df %>%
group_by(PatientID, BookingID) %>%
mutate(Key = paste(Level1, Level2, Value, collapse=";")) %>%
ungroup() %>%
select(-Level1, -Level2, -Value) %>%
distinct(PatientID, Key, .keep_all=TRUE) %>%
mutate(Key = str_split(Key, ";")) %>%
unnest(Key) %>%
separate(Key, into=c("Level1", "Level2", "Value"),
sep=" ", remove=TRUE) %>%
arrange(PatientID, BookingID, Level1, Level2)
# A tibble: 7 × 5
PatientID BookingID Level1 Level2 Value
* <chr> <chr> <chr> <chr> <chr>
1 a1 101-A1 1 HBA1C 9.4
2 a1 101-A1 1 VLDL 11
3 a1 101-A1 2 POL 10
4 a2 102-A2 1 LDL 116
5 a2 102-A2 1 VLDL 10
6 a2 103-A2 1 LDL 116
7 a2 103-A2 1 VLDL 11
我尝试使用Dplyr包中的以下代码,但这会删除我们想要的内容:
abcTest1 <- FullData %>% group_by(level1, patientId, value) %>% slice(1)
abcTest1%group\u by(level1,patientId,value)%%>%slice(1)
我似乎无法正确执行此操作,请提供输入使用优秀的软件包以简单的方式执行此操作:
install.packages(“data.table”)
库(数据表)
FullData%%as.data.table
abcTest1%唯一性(由=c(“级别1”、“患者ID”、“值”))
这是duplicated()
函数的经典用法。此函数用于确定向量或数据帧的唯一元素,并返回一个逻辑值,该值指示在对象中较早看到的元素。在这种情况下,我们可以对要查找其唯一元素的数据帧列使用duplicated()
,并使用输出进行索引
> df[!duplicated(df[c("PatientID", "Level1", "Value")]), ]
PatientID BookingID Level1 Level2 Value
1 a1 101-A1 1 HBA1C 9.4
2 a2 102-A2 1 LDL 116.0
3 a1 101-A1 1 VLDL 11.0
4 a1 101-A1 2 POL 10.0
6 a2 102-A2 1 VLDL 10.0
9 a2 103-A2 1 VLDL 11.0
我的输出与您的略有不同,因为第二行的值
116
不在那里,但根据您的描述,我认为这是示例中的一个错误。您只需使用unique
PatientID <- c("a1","a2","a1")
BookingID <- c("num1","num2","num1")
Level1 <- c(1,2,1)
Level2 <- c("HBA", "CDA", "HBA")
Value <- c(10,4,10)
df <- data.frame(PatientID,BookingID,Level1,Level2,Value)
df <- unique(df)
PatientID您也可以这样做:
library(dplyr)
> df
# A tibble: 10 × 5
PatientID BookingID Level1 Level2 Value
<chr> <chr> <dbl> <chr> <dbl>
1 a1 101-A1 1 HBA1C 9.4
2 a2 102-A2 1 LDL 116.0
3 a1 101-A1 1 VLDL 11.0
4 a1 101-A1 2 POL 10.0
5 a1 102-A1 1 HBA1c 9.4
6 a2 102-A2 1 VLDL 10.0
7 a1 102-A1 1 VLDL 11.0
8 a2 103-A2 1 LDL 116.0
9 a2 103-A2 1 VLDL 11.0
10 a1 102-A1 2 POL 10.0
> df %>% distinct(PatientID, Level1, Value, .keep_all=TRUE)
# A tibble: 6 × 5
PatientID BookingID Level1 Level2 Value
<chr> <chr> <dbl> <chr> <dbl>
1 a1 101-A1 1 HBA1C 9.4
2 a2 102-A2 1 LDL 116.0
3 a1 101-A1 1 VLDL 11.0
4 a1 101-A1 2 POL 10.0
5 a2 102-A2 1 VLDL 10.0
6 a2 103-A2 1 VLDL 11.0
基本上,我们首先从我们最感兴趣的三个值开始,Level1
、Level2
、和Value
,然后放入一个字符串,在该字符串中,我们用分号分隔每个BookingID
的每组值。这将为我们提供两行信息,分别是PatientID==a1
和PatientID==a2
,总共四行。然后,我们仅通过PatientID
和Key
进行重复数据消除,但同时告诉R保留BookingID
。我们发现a1
的数据相同,但a2
的数据不同,因为Value
其中Level2==POL
在两次就诊中不相同。因此,在重复数据消除之后,剩下三行。然后,我们使用分号作为分隔符拆分Key
,然后separate
Key
变量以恢复原始列。我可以问一下,您为什么要在您的问题中添加标签mysql
、excel
和sqlite
?这个问题似乎与其中任何一个都无关。我可能选择了unique
、subset
或dataframe
。@Barker我可以选择在任何工具上执行此操作,因为sqldf Package支持sql语法请不要麻烦使用一致的列名称。无论如何,这个函数的dplyr函数是DF%>%distinct(Level1,PatientID,Value)
我认为这不起作用,因为unique()
将查看所有列,而BookingID
和Level2
列将导致问题。Barker,但问题要求它在所有列中都是唯一的,不是吗?巴克,这会导致什么样的问题,你能运行我的代码一次并检查一下吗?它是根据询问者的要求重新生成的“一组由“级别1”、“patientID”及其“值”的一个组合组成,如果patientID a1两次参加测试——101-a1和102-a1,并且如果所有测试值相同,则只剩下其中一个,因此只有Level1
、PatientID
和Value
重要,而不是BookingID
或Level2
。您的示例之所以有效,是因为您在不同的数据上使用它。我在询问者的数据上运行了它,没有删除任何内容。您可以使用read.table(text=“copyAndPasteTextHere”,header=TRUE)
轻松读取他们的数据。@Barker您可以提出其他建议吗?请正确理解问题-patientID a2在最后一列“11”中有一个不同的vldl值,因此,该patientID的特定级别1的所有其他值需要保持不变,因此使用值为116的第二行needed@Rohan你想要的是;如果PatientID
和Level1
的所有唯一组合具有相同的值
,则返回PatientID
和Level1
的唯一值;否则返回该PatientID
的所有数据?是的,这个想法是如果一名患者来进行三次1级测试-假设1级有20个不同的测试(由2级显示),那么如果在所有20*3条目中,前20个值重复3次,那么我们取唯一的值,否则即使有一个不匹配,我们保留所有信息,因为这一步的问题是,如果有一个非常大的数据集…那么可能会发生这样的情况,即使整个二级测试的一级值可能不同-但如果一些二级值相同,这些值将被删除-尽管它们将处于相同的一级。哇,添加库(magrittr)abcTest1%唯一性(by=(“level1”,“patientId”,“value”))错误:意外”,“in”abcTest1%unique(by=(“level1”,“Hey Andrew,你能解释一下你的代码和我的代码之间的区别吗:abcTest1%unique(by=c(“level1”,“patientId”,“value”))abcTest1%group_by(level1,patientId,value)%>%slice(1)我检查了我的代码得到的输出与你的相同,我没有