在 R 中查找唯一的元组但忽略顺序
Finding unique tuples in R but ignoring order
由于我的数据要复杂得多,所以我制作了一个较小的样本数据集(我保留了重塑以显示我是如何生成数据的)。
set.seed(7)
x = rep(seq(2010,2014,1), each=4)
y = rep(seq(1,4,1), 5)
z = matrix(replicate(5, sample(c("A", "B", "C", "D"))))
temp_df = cbind.data.frame(x,y,z)
colnames(temp_df) = c("Year", "Rank", "ID")
head(temp_df)
require(reshape2)
dcast(temp_df, Year ~ Rank)
这导致...
> dcast(temp_df, Year ~ Rank)
Using ID as value column: use value.var to override.
Year 1 2 3 4
1 2010 D B A C
2 2011 A C D B
3 2012 A B D C
4 2013 D A C B
5 2014 C A B D
现在我基本上想使用类似 unique 的函数,但忽略顺序来查找前 3 个元素在何处是唯一的。
因此在这种情况下:
我会在第 5 行有 A、B、C
我会在第 1 行和第 3 行中有 A、B、D
我会在第 2 行和第 4 行有 A、C、D
我还需要这些 "unique" 事件的计数
还有两件事。首先,我的值是字符串,我需要将它们保留为字符串。
其次,如果可能的话,我会在年份和 1 之间设置一个列,称为权重,然后在计算这些独特的组合时,我会包括每个组合的权重。这并不重要,因为所有权重都是小的正整数值,因此我可能会更早地复制行以说明权重,然后将唯一对制成表格。
你可以这样做:
df <- dcast(temp_df, Year ~ Rank)
combos <- apply(df[, 2:4], 1, function(x) paste0(sort(x), collapse = ""))
combos
# 1 2 3 4 5
# "BCD" "ABC" "ACD" "BCD" "ABC"
对于数据框的每一行,第 1、2 和 3 列中的值(在 post 中标记)使用 sort
排序,然后使用 paste0
连接].由于顺序无关紧要,这可确保相同案例的标记一致。
请注意,paste0
函数等同于 paste(..., sep = "")
。 collapse
参数表示将向量的值连接成一个字符串,向量值由传递给 collapse
的值分隔。在这种情况下,我们设置 collapse = ""
,这意味着值之间将没有分隔,从而导致 "ABC"
、"ACD"
等
然后你可以使用 table
:
得到每个组合的计数
table(combos)
# ABC ACD BCD
# 2 1 2
这与@Alex_A 的解决方案相同,但使用了 tidyverse 函数:
library(purrr)
library(dplyr)
df <- dcast(temp_df, Year ~ Rank)
distinct(df, ID = pmap_chr(select(df, num_range("", 1:3)),
~paste0(sort(c(...)), collapse="")))
由于我的数据要复杂得多,所以我制作了一个较小的样本数据集(我保留了重塑以显示我是如何生成数据的)。
set.seed(7)
x = rep(seq(2010,2014,1), each=4)
y = rep(seq(1,4,1), 5)
z = matrix(replicate(5, sample(c("A", "B", "C", "D"))))
temp_df = cbind.data.frame(x,y,z)
colnames(temp_df) = c("Year", "Rank", "ID")
head(temp_df)
require(reshape2)
dcast(temp_df, Year ~ Rank)
这导致...
> dcast(temp_df, Year ~ Rank)
Using ID as value column: use value.var to override.
Year 1 2 3 4
1 2010 D B A C
2 2011 A C D B
3 2012 A B D C
4 2013 D A C B
5 2014 C A B D
现在我基本上想使用类似 unique 的函数,但忽略顺序来查找前 3 个元素在何处是唯一的。
因此在这种情况下:
我会在第 5 行有 A、B、C
我会在第 1 行和第 3 行中有 A、B、D
我会在第 2 行和第 4 行有 A、C、D
我还需要这些 "unique" 事件的计数
还有两件事。首先,我的值是字符串,我需要将它们保留为字符串。 其次,如果可能的话,我会在年份和 1 之间设置一个列,称为权重,然后在计算这些独特的组合时,我会包括每个组合的权重。这并不重要,因为所有权重都是小的正整数值,因此我可能会更早地复制行以说明权重,然后将唯一对制成表格。
你可以这样做:
df <- dcast(temp_df, Year ~ Rank)
combos <- apply(df[, 2:4], 1, function(x) paste0(sort(x), collapse = ""))
combos
# 1 2 3 4 5
# "BCD" "ABC" "ACD" "BCD" "ABC"
对于数据框的每一行,第 1、2 和 3 列中的值(在 post 中标记)使用 sort
排序,然后使用 paste0
连接].由于顺序无关紧要,这可确保相同案例的标记一致。
请注意,paste0
函数等同于 paste(..., sep = "")
。 collapse
参数表示将向量的值连接成一个字符串,向量值由传递给 collapse
的值分隔。在这种情况下,我们设置 collapse = ""
,这意味着值之间将没有分隔,从而导致 "ABC"
、"ACD"
等
然后你可以使用 table
:
table(combos)
# ABC ACD BCD
# 2 1 2
这与@Alex_A 的解决方案相同,但使用了 tidyverse 函数:
library(purrr)
library(dplyr)
df <- dcast(temp_df, Year ~ Rank)
distinct(df, ID = pmap_chr(select(df, num_range("", 1:3)),
~paste0(sort(c(...)), collapse="")))