我正在尝试隔离数据中唯一的项目组 - 与关键列关联的唯一行组,而不是唯一项,这是大多数使用唯一函数的行。这个问题需要仔细阅读......所以请善待消化这个例子。
要明确,我不想要组列的唯一子集,也不想要项目的唯一子集,甚至不需要组和项目的唯一组合。我知道其他地方已经涵盖了unique() for more than one variable。我想要的是唯一的项目集,其中集合由组定义。
这是一个例子
set.seed(1234)
library(data.table)
A <- data.table(group = rep(c("A","B","C","D","E","F"),each = 4),
item = c(1, 2, 4, 3, 5, 2, 3, 6, 10, 12, 1, 2, 1, 2, 4, 3, 6, 3,
5, 2, 10, 12, 1, 2), c = runif(8))
A <- A[-23, ] #so we can have an example of unbalanced groups
> A
group item c
1: A 1 0.15904600
2: A 2 0.03999592
3: A 4 0.21879954
4: A 3 0.81059855
5: B 5 0.52569755
6: B 2 0.91465817
7: B 3 0.83134505
8: B 6 0.04577026
9: C 10 0.15904600
10: C 12 0.03999592
11: C 1 0.21879954
12: C 2 0.81059855
13: D 1 0.52569755
14: D 2 0.91465817
15: D 4 0.83134505
16: D 3 0.04577026
17: E 6 0.15904600
18: E 3 0.03999592
19: E 5 0.21879954
20: E 2 0.81059855
21: F 10 0.52569755
22: F 12 0.91465817
23: F 2 0.04577026
#The unique groups are A:F, and the unique items are 1:6,10,12.
#The unique sets of items are: # (set1) 1,2,3,4; (set2) 5,2,3,6;
#(set3) 10,2,1,2; (set4) 10,12,2
我想要检索这些独特的项目集(再次注意项目集是由组形成的)。 (第三栏目前意义不大。为了好玩,我在每个“项目”中包含总和)。 输出表应如下所示:
group item c
A 1 0.68474355 #note that groups A and D share this same set of items (set1)
A 2 0.95465409
A 4 1.05014459# c sums groupAitem4$c with groupDitem4$c
A 3 0.85636881
B 5 0.74449709 # group E has the same items (set2), even if not the same order, c is totaled by item.
B 2 1.72525672
B 3 0.87134097
B 6 0.20481626
C 10 0.159046
C 12 0.03999592
C 1 0.21879954
C 2 0.81059855
F 10 0.52569755 #Not the same as group C
F 12 0.91465817
F 2 0.04577026
我想可能有一种方法可以通过重塑进行非常尴尬的方式。我的数据量很大,因此非常感谢像data.table
这样有效的程序。
答案 0 :(得分:2)
library(plyr)
my<-ddply(A,.(group),summarize, mylist=list(item))
> my
group mylist
1 A 1, 2, 4, 3
2 B 5, 2, 3, 6
3 C 10, 12, 1, 2
4 D 1, 2, 4, 3
5 E 6, 3, 5, 2
6 F 10, 12, 2
yy<-as.list(1:6) # used for `Map` function
my$mylist<-Map(function(x) sort(my$mylist[[x]]),yy) # sort the order of elements in list for matching
> my
group mylist
1 A 1, 2, 3, 4
2 B 2, 3, 5, 6
3 C 1, 2, 10, 12
4 D 1, 2, 3, 4
5 E 2, 3, 5, 6
6 F 2, 10, 12
myuni<-unique(my$mylist)
> myuni
[[1]]
[1] 1 2 3 4
[[2]]
[1] 2 3 5 6
[[3]]
[1] 1 2 10 12
[[4]]
[1] 2 10 12
finaloutput<-my[match(myuni,my$mylist),]
group mylist
1 A 1, 2, 3, 4
2 B 2, 3, 5, 6
3 C 1, 2, 10, 12
6 F 2, 10, 12
A[A$group %in% finaloutput$group,]
group item c
1 A 1 0.113703411
2 A 2 0.622299405
3 A 4 0.609274733
4 A 3 0.623379442
5 B 5 0.860915384
6 B 2 0.640310605
7 B 3 0.009495756
8 B 6 0.232550506
9 C 10 0.113703411
10 C 12 0.622299405
11 C 1 0.609274733
12 C 2 0.623379442
21 F 10 0.860915384
22 F 12 0.640310605
23 F 2 0.232550506
答案 1 :(得分:0)
如果你只需要组合
unique(dataset[, c("group", "item")])
答案 2 :(得分:0)
由于您不使用set.seed或dput,因此每个尝试使用您的代码的人都会得到不同的结果。这可能会给你你想要的东西,虽然目前还不清楚组中的项目数量是否总是很小,是否只是所需的2路组合:
unique(t(do.call(cbind, tapply(A$item, A$group, combn, 2) ) ) )
combn
函数以列格式返回唯一组合,因此我需要在使用默认情况下对行进行操作的unique
之前进行转置。如果您可以使用面向列的结果,则可以跳过该步骤,如果您使用MARGIN参数:
unique(do.call(cbind, tapply(A$item, A$group, combn, 2) ) , MARGIN=2)