R中多个变量的重复项
Duplicates for multiple variables in R
我有这段代码,我在其中加载了 CSV。这意味着删除具有相同值、字符、字符串等的重复行。在特定变量上,在本例中为 ID、DATE 和 Dx。
> alt
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE1
1 740010662 5 2 2 23 29 12 2009 40176 13 Z33.X 1 1 2010 40179 O82.9 please
2 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 help
3 705280124 5 2 2 33 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 me
4 791125002 5 2 1 30 30 12 2009 40177 13 O33.5 1 1 2010 40179 O82.9 im
5 469833092 5 2 1 26 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 really
6 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 desperate
7 410886387 5 2 2 29 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 been
8 486326736 5 2 1 37 30 12 2009 40177 13 O72.0 1 1 2010 40179 O82.9 banging
9 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 my
10 896565718 5 2 1 28 30 12 2009 40177 13 Z33.X 1 1 2010 40179 O82.9 head
11 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 to
12 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 the
13 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 wall
首先我加载了 csv
#1.Load database
BU<-read.csv(choose.files(),header = T,)
alt<- BU
后接此代码
# 2.eliminates duplicates according to multiple variables
# df1<-data frame with unique observations
# df2<-dataframe with duplicated observations
df1 <- alt[ !( duplicated(alt[,1]) & duplicated(alt[,9]) & duplicated(alt[,11]) ), ]
df2 <- alt[ !(!( duplicated(alt[,1]) & duplicated(alt[,9]) & duplicated(alt[,11]) )), ]
瞧,它起作用了,这就是结果。
> df1
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE
1 740010662 5 2 2 23 29 12 2009 40176 13 Z33.X 1 1 2010 40179 O82.9 please
2 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 help
3 705280124 5 2 2 33 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 me
4 791125002 5 2 1 30 30 12 2009 40177 13 O33.5 1 1 2010 40179 O82.9 im
5 469833092 5 2 1 26 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 really
6 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 desperate
7 410886387 5 2 2 29 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 been
8 486326736 5 2 1 37 30 12 2009 40177 13 O72.0 1 1 2010 40179 O82.9 banging
9 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 my
10 896565718 5 2 1 28 30 12 2009 40177 13 Z33.X 1 1 2010 40179 O82.9 head
> df2
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE
11 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 to
12 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 the
13 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 wall
有效。因为它删除了第 11、12 和 13 行,它们与第 2、6 和 9 行重复。
但是原始数据库大约有 18,000 个观察值和 27 个变量,并且代码 失败 。它似乎仅基于一个或两个变量而不是三个变量 ID、DATE 和 Dx 来考虑重复项。
我想你正在寻找
alt[!duplicated(alt[c('ID','DATE','Dx')]),];
当给定 data.frame 时,duplicated()
函数在决定哪些行是重复行时会考虑 data.frame 中的所有列。
但要注意警告:
The data frame method works by pasting together a character representation of the rows separated by \r, so may be imperfect if the data frame has characters with embedded carriage returns or columns which do not reliably map to characters.
回复您的评论:两者不等同。我的代码 selects 唯一行,而你的代码 selects 行至少有一个列,其单元格值不与列中的先前值重复。您的代码将无法处理 select 行,这些行的每个单元格值都是列中较高值的单独副本,但其行整体是相对于所有先前行的唯一行。
这里有一个简单的演示:
g <- expand.grid(x=1:3,y=4:6)[rep(1:9,2L),];
cbind(g,dennis=!duplicated(g$x) | !duplicated(g$y),bgoldst=!duplicated(g));
## x y dennis bgoldst
## 1 1 4 TRUE TRUE
## 2 2 4 TRUE TRUE
## 3 3 4 TRUE TRUE
## 4 1 5 TRUE TRUE
## 5 2 5 FALSE TRUE
## 6 3 5 FALSE TRUE
## 7 1 6 TRUE TRUE
## 8 2 6 FALSE TRUE
## 9 3 6 FALSE TRUE
## 1.1 1 4 FALSE FALSE
## 2.1 2 4 FALSE FALSE
## 3.1 3 4 FALSE FALSE
## 4.1 1 5 FALSE FALSE
## 5.1 2 5 FALSE FALSE
## 6.1 3 5 FALSE FALSE
## 7.1 1 6 FALSE FALSE
## 8.1 2 6 FALSE FALSE
## 9.1 3 6 FALSE FALSE
例如,请注意第一个不同的行 x=2 y=5
是如何被您的代码删除的,因为 x=2
是重复的并且 y=5
是重复的,但它包含在内根据我的代码,因为完整的 x=2 y=5
行对于所有先前的行都是唯一的。
我有这段代码,我在其中加载了 CSV。这意味着删除具有相同值、字符、字符串等的重复行。在特定变量上,在本例中为 ID、DATE 和 Dx。
> alt
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE1
1 740010662 5 2 2 23 29 12 2009 40176 13 Z33.X 1 1 2010 40179 O82.9 please
2 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 help
3 705280124 5 2 2 33 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 me
4 791125002 5 2 1 30 30 12 2009 40177 13 O33.5 1 1 2010 40179 O82.9 im
5 469833092 5 2 1 26 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 really
6 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 desperate
7 410886387 5 2 2 29 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 been
8 486326736 5 2 1 37 30 12 2009 40177 13 O72.0 1 1 2010 40179 O82.9 banging
9 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 my
10 896565718 5 2 1 28 30 12 2009 40177 13 Z33.X 1 1 2010 40179 O82.9 head
11 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 to
12 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 the
13 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 wall
首先我加载了 csv
#1.Load database
BU<-read.csv(choose.files(),header = T,)
alt<- BU
后接此代码
# 2.eliminates duplicates according to multiple variables
# df1<-data frame with unique observations
# df2<-dataframe with duplicated observations
df1 <- alt[ !( duplicated(alt[,1]) & duplicated(alt[,9]) & duplicated(alt[,11]) ), ]
df2 <- alt[ !(!( duplicated(alt[,1]) & duplicated(alt[,9]) & duplicated(alt[,11]) )), ]
瞧,它起作用了,这就是结果。
> df1
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE
1 740010662 5 2 2 23 29 12 2009 40176 13 Z33.X 1 1 2010 40179 O82.9 please
2 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 help
3 705280124 5 2 2 33 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 me
4 791125002 5 2 1 30 30 12 2009 40177 13 O33.5 1 1 2010 40179 O82.9 im
5 469833092 5 2 1 26 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 really
6 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 desperate
7 410886387 5 2 2 29 31 12 2009 40178 13 Z33.X 1 1 2010 40179 O80.9 been
8 486326736 5 2 1 37 30 12 2009 40177 13 O72.0 1 1 2010 40179 O82.9 banging
9 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 my
10 896565718 5 2 1 28 30 12 2009 40177 13 Z33.X 1 1 2010 40179 O82.9 head
> df2
ID RISK GENDER STATUS AGE DAY MONTH YEAR DATE SALA Dx DAY2 MONTH2 YEAR2 DATE2 Dx1 STATE
11 347866388 5 2 1 23 31 12 2009 40178 13 O06.4 1 1 2010 40179 O06.4 to
12 855318644 5 2 1 35 30 12 2009 40177 13 O47.9 1 1 2010 40179 O80.9 the
13 995190824 5 2 1 22 1 1 2010 40179 13 Z33.X 1 1 2010 40179 O80.9 wall
有效。因为它删除了第 11、12 和 13 行,它们与第 2、6 和 9 行重复。
但是原始数据库大约有 18,000 个观察值和 27 个变量,并且代码 失败 。它似乎仅基于一个或两个变量而不是三个变量 ID、DATE 和 Dx 来考虑重复项。
我想你正在寻找
alt[!duplicated(alt[c('ID','DATE','Dx')]),];
当给定 data.frame 时,duplicated()
函数在决定哪些行是重复行时会考虑 data.frame 中的所有列。
但要注意警告:
The data frame method works by pasting together a character representation of the rows separated by \r, so may be imperfect if the data frame has characters with embedded carriage returns or columns which do not reliably map to characters.
回复您的评论:两者不等同。我的代码 selects 唯一行,而你的代码 selects 行至少有一个列,其单元格值不与列中的先前值重复。您的代码将无法处理 select 行,这些行的每个单元格值都是列中较高值的单独副本,但其行整体是相对于所有先前行的唯一行。
这里有一个简单的演示:
g <- expand.grid(x=1:3,y=4:6)[rep(1:9,2L),];
cbind(g,dennis=!duplicated(g$x) | !duplicated(g$y),bgoldst=!duplicated(g));
## x y dennis bgoldst
## 1 1 4 TRUE TRUE
## 2 2 4 TRUE TRUE
## 3 3 4 TRUE TRUE
## 4 1 5 TRUE TRUE
## 5 2 5 FALSE TRUE
## 6 3 5 FALSE TRUE
## 7 1 6 TRUE TRUE
## 8 2 6 FALSE TRUE
## 9 3 6 FALSE TRUE
## 1.1 1 4 FALSE FALSE
## 2.1 2 4 FALSE FALSE
## 3.1 3 4 FALSE FALSE
## 4.1 1 5 FALSE FALSE
## 5.1 2 5 FALSE FALSE
## 6.1 3 5 FALSE FALSE
## 7.1 1 6 FALSE FALSE
## 8.1 2 6 FALSE FALSE
## 9.1 3 6 FALSE FALSE
例如,请注意第一个不同的行 x=2 y=5
是如何被您的代码删除的,因为 x=2
是重复的并且 y=5
是重复的,但它包含在内根据我的代码,因为完整的 x=2 y=5
行对于所有先前的行都是唯一的。