删除 Data Frame 中的公共元素
Remove common elements in Data Frame
作为问题启动一个单独的线程现在略有不同()。我有一个包含任意列数的数据框,我想删除所有列都不是唯一的元素。建议使用 intersect
但它只会删除所有列中存在的元素(见下文)。我需要删除在超过 1 列中看到的任何元素。并且需要一个向量化的解决方案——现在我可以做到,但使用 N 个向量确实很乏味。
谢谢!
这个工作完成了,但只针对每一列中出现的元素:
df1 = structure(list(A = structure(1:3, .Label = c("R1", "R2", "R3"), class = "factor"),
B = c("1 4 78 5 4 6 7 0",
"2 3 76 8 2 1 8 0",
"4 7 1 2"
)), .Names = c("A", "B"), row.names = c(NA, -3L), class = "data.frame")
s <- strsplit(df1$B, " ")
## find the intersection of all s
r <- Reduce(intersect, s)
## iterate over s, removing the intersection characters in r
l <- lapply(s, function(x) x[!x %in% r])
## reset the length of each vector in l to the length of the longest vector
## then create the new data frame
zz = setNames(as.data.frame(lapply(l, "length<-", max(sapply(l, length)))), letters[seq_along(l)])
编辑。我很抱歉 - 应该包含所需的输出。这是:
Col1 Col2 Col3
78 3 NA
5 76 NA
6 8 NA
NA 8 NA
您可以从每个列表中创建一个 table 唯一值,并删除那些计数大于 1 的值。
tab <- table(unlist(sapply(s, unique))) < 2
lapply(s, function(x) x[tab[x]])
也许
s <- strsplit(df1$B, " ")
n <- max(sapply(s,length))
M <- sapply(s,function(x){c(x,rep(Inf,n-length(x)))})
u <- unique(unlist(s))
r <- u[sapply(u,function(x){sum(rowSums(M==x)>0)>1})]
然后
> r
[1] "1" "4" "7" "2" "8"
是必须删除的元素。 "Inf" 用于用 "df1$B" 中未出现的内容填充矩阵 "M" 中的空白。矩阵 "M" 转置为 "df1$B"。因此,我使用 "rowSums" 来检查元素是否出现在 "df1$B" 的列中。如果 "df1$B" 中的字符串是列,请将 "rowSums" 替换为 "colSums"。
作为问题启动一个单独的线程现在略有不同(intersect
但它只会删除所有列中存在的元素(见下文)。我需要删除在超过 1 列中看到的任何元素。并且需要一个向量化的解决方案——现在我可以做到,但使用 N 个向量确实很乏味。
谢谢!
这个工作完成了,但只针对每一列中出现的元素:
df1 = structure(list(A = structure(1:3, .Label = c("R1", "R2", "R3"), class = "factor"),
B = c("1 4 78 5 4 6 7 0",
"2 3 76 8 2 1 8 0",
"4 7 1 2"
)), .Names = c("A", "B"), row.names = c(NA, -3L), class = "data.frame")
s <- strsplit(df1$B, " ")
## find the intersection of all s
r <- Reduce(intersect, s)
## iterate over s, removing the intersection characters in r
l <- lapply(s, function(x) x[!x %in% r])
## reset the length of each vector in l to the length of the longest vector
## then create the new data frame
zz = setNames(as.data.frame(lapply(l, "length<-", max(sapply(l, length)))), letters[seq_along(l)])
编辑。我很抱歉 - 应该包含所需的输出。这是:
Col1 Col2 Col3
78 3 NA
5 76 NA
6 8 NA
NA 8 NA
您可以从每个列表中创建一个 table 唯一值,并删除那些计数大于 1 的值。
tab <- table(unlist(sapply(s, unique))) < 2
lapply(s, function(x) x[tab[x]])
也许
s <- strsplit(df1$B, " ")
n <- max(sapply(s,length))
M <- sapply(s,function(x){c(x,rep(Inf,n-length(x)))})
u <- unique(unlist(s))
r <- u[sapply(u,function(x){sum(rowSums(M==x)>0)>1})]
然后
> r
[1] "1" "4" "7" "2" "8"
是必须删除的元素。 "Inf" 用于用 "df1$B" 中未出现的内容填充矩阵 "M" 中的空白。矩阵 "M" 转置为 "df1$B"。因此,我使用 "rowSums" 来检查元素是否出现在 "df1$B" 的列中。如果 "df1$B" 中的字符串是列,请将 "rowSums" 替换为 "colSums"。