Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用'dplyr'识别'data.frame'中的重复项`_R_Dplyr - Fatal编程技术网

使用'dplyr'识别'data.frame'中的重复项`

使用'dplyr'识别'data.frame'中的重复项`,r,dplyr,R,Dplyr,我想使用Rdplyr包识别(而不是消除)数据帧中的重复项,并相应地添加0/1变量(无论一行是否重复) 例如: | A B C D 1 | 1 0 1 1 2 | 1 0 1 1 3 | 0 1 1 1 4 | 0 1 1 1 5 | 1 1 1 1 显然,第1行和第2行是重复的,所以我想创建一个新变量(使用mutate?),比如E,它等于第1、2、3和4行中的1,因为第3行和第4行也是相同的 此外,我还想添加另一个变量,F,如果存在只相差一列的副本,则该变量等于1。也就是说,第1、2和5行

我想使用R
dplyr
包识别(而不是消除)数据帧中的重复项,并相应地添加0/1变量(无论一行是否重复)

例如:

  | A B C D
1 | 1 0 1 1
2 | 1 0 1 1
3 | 0 1 1 1
4 | 0 1 1 1
5 | 1 1 1 1
显然,第1行和第2行是重复的,所以我想创建一个新变量(使用
mutate
?),比如
E
,它等于第1、2、3和4行中的1,因为第3行和第4行也是相同的

此外,我还想添加另一个变量,
F
,如果存在只相差一列的副本,则该变量等于1。也就是说,第1、2和5行中的
F
将等于1,因为它们仅在
B
列中不同


我希望我想做的事情很清楚,我希望dplyr能够顺利解决这个问题。当然,这在“base”R中是可能的,但我相信(希望)存在一个更平滑的解决方案。

这里有一个
数据表
解决方案,可以扩展到任意情况(1..n列相同)-不确定是否有人可以为您转换为
dpylr
。我不得不稍微修改一下数据集以显示所需的F列—在您的示例中,所有行都将得到1,因为3和4也是一个与5不同的列

library(data.table)

DT <- data.frame(A = c(1,1,0,0,1), B = c(0,0,1,1,1), C = c(1,1,1,1,1), D = c(1,1,1,1,1), E = c(1,1,0,0,0))
DT
  A B C D E
1 1 0 1 1 1
2 1 0 1 1 1
3 0 1 1 1 0
4 0 1 1 1 0
5 1 1 1 1 0

setDT(DT)
DT_ncols <- length(DT)

base <- data.table(t(combn(1:nrow(DT), 2)))
setnames(base, c("V1","V2"),c("ind_x","ind_y"))

DT[, ind := .I)]

DT_melt <- melt(DT, id.var = "ind", variable.name = "column")

base <- merge(base, DT_melt, by.x = "ind_x", by.y = "ind", allow.cartesian = TRUE)
base <- merge(base, DT_melt, by.x = c("ind_y", "column"), by.y = c("ind", "column"))

base <- base[, .(common_cols = sum(value.x == value.y)), by = .(ind_x, ind_y)]
这表示第1行和第2行有5个公共列(重复)。第3行和第5行有4个公共列,第4行和第5行有4个公共列。我们现在可以使用一种相当可扩展的格式来标记我们想要的任何组合:

base <- melt(base, id.vars = "common_cols")
# Unique - common_cols == DT_ncols
DT[, F := ifelse(ind %in% unique(base[common_cols == DT_ncols, value]), 1, 0)]
# Same save 1 - common_cols == DT_ncols - 1
DT[, G := ifelse(ind %in% unique(base[common_cols == DT_ncols - 1, value]), 1, 0)]
# Same save 2 - common_cols == DT_ncols - 2
DT[, H := ifelse(ind %in% unique(base[common_cols == DT_ncols - 2, value]), 1, 0)]
您可以像这样附加所有组合,而不是手动选择:

# run after base <- melt(base, id.vars = "common_cols")
base <- unique(base[,.(ind = value, common_cols)])
base[, common_cols := factor(common_cols, 1:DT_ncols)]
merge(DT, dcast(base, ind ~ common_cols, fun.aggregate = length, drop = FALSE), by = "ind")
   ind A B C D E 1 2 3 4 5
1:   1 1 0 1 1 1 0 1 1 0 1
2:   2 1 0 1 1 1 0 1 1 0 1
3:   3 0 1 1 1 0 0 1 0 1 1
4:   4 0 1 1 1 0 0 1 0 1 1
5:   5 1 1 1 1 0 0 0 1 1 0

#在base之后运行这里有一个dplyr解决方案:

test%>%mutate(flag =         (A==lag(A)&
                              B==lag(B)&
                              C==lag(C)&
                              D==lag(D)))%>%
  mutate(twice = lead(flag)==T)%>%
  mutate(E = ifelse(flag == T | twice ==T,1,0))%>%
  mutate(E = ifelse(is.na(E),0,1))%>%
  mutate(FF = ifelse( ( (A +lag(A)) + (B +lag(B)) + (C+lag(C)) + (D + lag(D))) == 7,1,0))%>%
  mutate(FF = ifelse(is.na(FF)| FF == 0,0,1))%>%
  select(A,B,C,D,E,FF)
结果:

  A B C D E FF
1 1 0 1 1 1  0
2 1 0 1 1 1  0
3 0 1 1 1 1  0
4 0 1 1 1 1  0
5 1 1 1 1 0  1
您可以使用
dist()
计算差异,然后在生成的距离对象中进行搜索可以给出所需的答案(E、F等)。下面是一个示例代码,其中
X
是原始
数据。frame

W=as.matrix(dist(X, method="manhattan"))
X$E = as.integer(sapply(1:ncol(W), function(i,D){any(W[-i,i]==D)}, D=0))
X$F = as.integer(sapply(1:ncol(W), function(i,D){any(W[-i,i]==D)}, D=1))
只需更改
D=
即可获得所需的不同列数。
不过都是些卑鄙的人。使用
plyr::laply
而不是
sappy
具有相同的效果
dplyr
在这里看起来有些过分。

若要使用
dplyr
识别重复项,您可以尝试使用
distinct
E
变量,
as.integer(duplicated(d2)| duplicated(d2,fromLast=TRUE))
为列E创建第二个已消除但已计数的重复行的TIBLE,然后重新连接新的TIBLE,但是只有count列作为E,指向旧的tible(包含重复的行)。对于F列,可以执行相同的步骤,但在这两个步骤之间,还可以添加另一个带有mutate的字段,使用mutate右侧的complex或conditions)。为什么
F
不是1,2,3,4,5?第3行和第4行与第5行也只有一列不同,
A
  A B C D E FF
1 1 0 1 1 1  0
2 1 0 1 1 1  0
3 0 1 1 1 1  0
4 0 1 1 1 1  0
5 1 1 1 1 0  1
W=as.matrix(dist(X, method="manhattan"))
X$E = as.integer(sapply(1:ncol(W), function(i,D){any(W[-i,i]==D)}, D=0))
X$F = as.integer(sapply(1:ncol(W), function(i,D){any(W[-i,i]==D)}, D=1))