我正在尝试在数据框中实现类似于
unique
的操作,其中行中每个列元素都是向量。我想要做的是,如果该行中列的向量元素是另一个向量的子集或相等,则删除具有较少元素数的行。使用嵌套的for
循环可以实现此操作,但由于数据包含400,000行,程序效率非常低。
样例数据:
# Set the seed for reproducibility
set.seed(42)
# Create a random data frame
mydf <- data.frame(items = rep(letters[1:4], length.out = 20),
grps = sample(1:5, 20, replace = TRUE),
supergrp = sample(LETTERS[1:4], replace = TRUE))
# Aggregate items into a single column
temp <- aggregate(items ~ grps + supergrp, mydf, unique)
# Arrange by number of items for each grp and supergroup
indx <- order(lengths(temp$items), decreasing = T)
temp <- temp[indx, ,drop=FALSE]
临时文件的外观如下
grps supergrp items
1 4 D a, c, d
2 3 D c, d
3 5 D a, d
4 1 A b
5 2 A b
6 3 A b
7 4 A b
8 5 A b
9 1 D d
10 2 D c
现在您可以看到第二行和第三行的超组和项目的第二个组合包含在第一行中。因此,我想从结果中删除第二行和第三行。同样,第5到8行包含在第4行中。最后,第9和第10行包含在第一行中,所以我想删除第9和第10行。因此,我的结果应该如下:
grps supergrp items
1 4 D a, c, d
4 1 A b
我的实现如下:
# initialise the result dataframe by first row of old data frame
newdf <-temp[1, ]
# For all rows in the the original data
for(i in 1:nrow(temp))
{
# Index to check if all the items are found
indx <- TRUE
# Check if item in the original data appears in the new data
for(j in 1:nrow(newdf))
{
if(all(c(temp$supergrp[[i]], temp$items[[i]]) %in%
c(newdf$supergrp[[j]], newdf$items[[j]]))){
# set indx to false if a row with same items and supergroup
# as the old data is found in the new data
indx <- FALSE
}
}
# If none of the rows in new data contain items and supergroup in old data append that
if(indx){
newdf <- rbind(newdf, temp[i, ])
}
}
我相信有一种有效的方法可以在R中实现这个,可能使用tidy
框架和dplyr
链,但我不知道诀窍。对于一个比较长的问题,我感到抱歉。任何意见将不胜感激。
igraph
包找到将每个grp/supergrp
配对链接到items
的图形,然后您可以为每个组分配一个“集群”,以确定共享哪些items
。 - thelatemaillibrary(igraph); int <- interaction(mydf[c("grps","supergrp")]); g <- graph.data.frame(cbind(mydf["items"],int)); clg <- clusters(g); mydf$clusters <- clg$membership[match(int, names(clg$membership))]
这样分配集群标识符。 - thelatemail