1

したがって、長さが150000の文字ベクトルがあるとします。ベクトル内の文字列は一意ではありません。実際、最も頻繁に存在する文字列が28回、さらに24回、1000回以上が5回以上存在する正規分布です。ベクトルを28個の小さなベクトルに分割し、文字列を小さなベクトルに分散して、各小さなベクトルに2回以上文字列が存在しないようにします。理想的には、1回だけ(または存在しない)にします。すべての文字列を保持する必要があるため、単純に実行することはできません。!duplicated()理想的には、ベクトルはほぼ同じサイズになります。

どのように私はこれをしますか?

最初の一意でない文字列に遭遇するまで最初のベクトルに追加を開始し、それをスキップし、150000/28 = 5357に達するまでスキップする一意でない文字列を埋め続けてから、他のベクトルを続行するようなものを考えています。同様に、小さい文字列に割り当てられた文字列を親ベクトルから削除しますか?これに関する問題はありますか?forループの厄介な森なしでそれを行う効率的な方法は?

4

2 に答える 2

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ことを確認します。自信が持てるまで繰り返します。sf

> 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
于 2012-12-13T00:24:27.363 に答える
0

これは、各文字列が発生する頻度を集計し、「i回以上出現する文字列」に基づいて分割することで、要件(各文字列はサブベクトルごとに1回のみ)をかなり簡潔に満たします。

inputs <- c("foo", "bar", "baz", "bar", "baz", "bar", "bar")
histo <- table(inputs)
lapply(1:max(histo), function(i) { names(histo)[histo>=i] } 

もちろん、これにより、サイズが大きく異なるパーティションが生成されますが、その領域での要件が明確ではありません。

于 2012-12-12T11:08:52.993 に答える