需要根据产品和群集的大小对数据进行群集。这是一个可重复的例子:
Output <- fread('User_ID,Product,Cluster
A,"P1",1
B,"P1",1
C,"P1",1
D,"P1",2
E,"P2",3
F,"P2",3
G,"P3",4
H,"P3",4
I,"P3",4
J,"P3",5
K,"P3",5
L,"P3",5
M,"P3",6')
群集的最大大小不能大于3.此外,每个群集只应包含一种类型的产品。 我正在寻找的输出是:
Var textbooks = [ ];
textbooks.push( javabook );
textbooks.push( vb6book );
console.log("Whole obj - -> ",textbooks)
答案 0 :(得分:4)
这是一个data.table方法。
mydata[, cluster := as.integer(factor(paste(Product, (rowid(Product) - 1L) %/% 3)))]
我们的想法是将产品粘贴到产品rowid
的输出中,该产品会单独计算每个产品。从此计数中减去1并使用%/%
得到整数除法结果。将字符向量转换为一个因子,它将以字面顺序对数据进行排序,然后再为整数。
返回
mydata
User_ID Product cluster
1: A P1 1
2: B P1 1
3: C P1 1
4: D P1 2
5: E P2 3
6: F P2 3
7: G P3 4
8: H P3 4
9: I P3 4
10: J P3 5
11: K P3 5
12: L P3 5
13: M P3 6
效率的潜在改进是使用interaction
代替paste
/ factor
,如下所示:
mydata[, cluster := as.integer(interaction(Product, (rowid(Product) - 1L) %/% 3,
lex.order=TRUE))]
返回的值仍然正确聚类,并且是有序的,但它们不直接遵循自然数序列。
mydata
User_ID Product cluster
1: A P1 1
2: B P1 1
3: C P1 1
4: D P1 2
5: E P2 4
6: F P2 4
7: G P3 7
8: H P3 7
9: I P3 7
10: J P3 8
11: K P3 8
12: L P3 8
13: M P3 9
答案 1 :(得分:1)
请试试这个。我希望这可以进一步优化:
test=mydata%>%group_by(Product)%>%mutate(count = n())%>%ungroup()
.GlobalEnv$counter = 0;
clust = ddply(.data = test,.variables = c('Product'),function(t){
if(t$count[1]<=3){
.GlobalEnv$counter=.GlobalEnv$counter+1;
Cluster = rep(.GlobalEnv$counter,t$count[1])
t = cbind(t,Cluster)
}else{
.GlobalEnv$counter=.GlobalEnv$counter+1;
factor=floor(t$count[1]/3);
if(t$count[1]%%3==0){
Cluster = rep(seq(.GlobalEnv$counter,.GlobalEnv$counter+(factor-1),by = 1),each=3)
t = cbind(t,Cluster)
}else{
tempclust = rep(seq(.GlobalEnv$counter,.GlobalEnv$counter+(factor-1),by = 1),each=3)
.GlobalEnv$counter = .GlobalEnv$counter+factor
Cluster = c(tempclust,rep(.GlobalEnv$counter,each=(t$count[1]%%3)))
t = cbind(t,Cluster)
}
}})
clust%>%select(Product,User_ID,Cluster)
# Product User_ID Cluster
#1 P1 A 1
#2 P1 B 1
#3 P1 C 1
#4 P1 D 2
#5 P2 E 3
#6 P2 F 3
#7 P3 G 4
#8 P3 H 4
#9 P3 I 4
#10 P3 J 5
#11 P3 K 5
#12 P3 L 5
#13 P3 M 6
此逻辑可能仅适用于奇数编号的组长度,在这种情况下为3。
答案 2 :(得分:0)
这是另一种解决方案:
my_data_grp <- mydata %>%
group_by(Product) %>%
summarise(count= n())
my_data_grp$counter <- 1:nrow(my_data_grp)
mydata <- merge(mydata,my_data_grp,by = 'Product')
cnt=0
fin=data.frame()
for (i in 1:nrow(my_data_grp)){
temp= mydata %>%
filter(counter==my_data_grp$counter[i])
#print(final_ProductGrp$cnt[i])
temp$index = 1:nrow(temp)
temp$quotient = ceiling(temp$index/3)+cnt
cnt=max(temp$quotient)
fin <- rbind(fin,temp)
}
View(fin)
提供所需的输出。