因此,假设我有一个长度为150000的字符向量。向量中的字符串并不是唯一的,实际上它们通常是分布式的,其中最频繁的字符串存在28次,另外24个字符串存在超过1000个字符串。 5次。我想将矢量划分为28个较小的矢量,在较小的矢量中分配字符串,使得在每个较小的矢量中不存在超过两次的字符串,理想情况下仅一次(或不存在)。我需要保留每个字符串,所以我不能只做!duplicated()
理想情况下,矢量的大小大致相同。
我该怎么做?
我正在考虑开始添加到第一个向量,直到遇到第一个非唯一字符串,跳过它,继续填写跳过非唯一字符串,直到达到150000/28 = 5357,然后继续其他向量的方式相同,一旦将它们分配给较小的一个,就从父向量中删除它们?这有什么问题吗?在没有令人讨厌的for循环森林的情况下有效地做到这一点?
答案 0 :(得分:1)
这似乎是一个非常有趣的问题,虽然它可能只是看起来很有趣,因为我误解了它 - 我在这里得到的解决方案创建了length of character vector / frequency of most frequent item
子向量,然后将每个字符串放入f
那些子向量,其中f
是该字符串的频率。这可能比你实际要求的要复杂得多。
library(plyr)
# I created a file with 10000 random strings and a roughly similar frequency
# distribution using python, and now I can't remember exactly what I did
strings <- read.csv("random_strings.txt", header=FALSE,
stringsAsFactors=FALSE)$V1
freq_table <- table(strings)
num_sub_vectors <- max(freq_table)
# Create a list of empty character vectors
split_list <- alply(1:num_sub_vectors, 1, function(x) return(character(0)))
for (s in names(freq_table)) {
# Put each string into f of the sub-vectors, where f is the string's
# frequency
freq <- freq_table[[s]]
# Choose f random indexes to put this string into
sub_vecs <- sample(1:num_sub_vectors, freq)
for (sub in sub_vecs) {
split_list[[sub]] <- c(split_list[[sub]], s)
}
}
要测试它是否有效,请选择一个字符串s
或频率f
,然后检查s
个子矢量中是否f
。重复,直到你有信心。
> head(freq_table[freq_table==15])
strings
ad ak bj cg cl cy
15 15 15 15 15 15
> sum(sapply(split_list, function(x) "ad" %in% x))
[1] 15
答案 1 :(得分:0)
通过统计每个字符串出现的频率然后根据“出现i次或更多次的字符串”进行分区,这非常简洁地满足您的要求(每个子字符串只有一个字符串):
inputs <- c("foo", "bar", "baz", "bar", "baz", "bar", "bar")
histo <- table(inputs)
lapply(1:max(histo), function(i) { names(histo)[histo>=i] }
这当然会产生大小不一的分区,但是你对这方面的要求并不十分清楚。