2017-02-28 10 views
0

ドメイン名のリスト(たとえばgoogle.com)を持っていて、ドメイン名の列とa-zからなる26の新しい列からなるデータフレームを作成したいと考えています。データフレームの行は、各ドメイン内に表示される各文字の数で構成する必要があります。私はそれが単一の行のために働くことができますが、データフレーム全体ではありません。ここで私はこれまで持っているものです。rの文字の出現を確認

df_letters = data_frame(domain = domain_df$domain) 
df_letters[, letters] = 0 
head(df_letters) 

    # A tibble: 6 × 27 
     domain  a  b  c  d  e  f  g  h  i  j  k  l 
      <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1 google.com  0  0  0  0  0  0  0  0  0  0  0  0 
2 youtube.com  0  0  0  0  0  0  0  0  0  0  0  0 
3 facebook.com  0  0  0  0  0  0  0  0  0  0  0  0 
4  baidu.com  0  0  0  0  0  0  0  0  0  0  0  0 
5  yahoo.com  0  0  0  0  0  0  0  0  0  0  0  0 
6 wikipedia.org  0  0  0  0  0  0  0  0  0  0  0  0 
# ... with 14 more variables: m <dbl>, n <dbl>, o <dbl>, p <dbl>, q <dbl>, r <dbl>, s <dbl>, 
# t <dbl>, u <dbl>, v <dbl>, w <dbl>, x <dbl>, y <dbl>, z <dbl> 
> 

df_letters$domain = str_trim(df_letters$domain, side = "both") 

df_letters[, 2:27] = str_count(df_letters$domain, letters) 

次の警告メッセージが誤って埋めdf_lettersデータフレームと一緒に表示されます:

Warning message: 
In stri_count_regex(string, pattern, opts_regex = opts(pattern)) : 
    longer object length is not a multiple of shorter object length 

# A tibble: 6 × 27 
     domain  a  b  c  d  e  f  g  h  i  j  k  l 
      <chr> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> 
1 google.com  0  0  0  0  0  0  0  0  0  0  0  0 
2 youtube.com  1  1  1  1  1  1  1  1  1  1  1  1 
3 facebook.com  2  2  2  2  2  2  2  2  2  2  2  2 
4  baidu.com  1  1  1  1  1  1  1  1  1  1  1  1 
5  yahoo.com  0  0  0  0  0  0  0  0  0  0  0  0 
6 wikipedia.org  0  0  0  0  0  0  0  0  0  0  0  0 
# ... with 14 more variables: m <int>, n <int>, o <int>, p <int>, q <int>, r <int>, s <int>, 
# t <int>, u <int>, v <int>, w <int>, x <int>, y <int>, z <int> 

誰でも助けることができますか?ここ

+1

私は '' df_letters [、2:27] = str_count(df_letters $ domain、letters) 'のように、複数の列2,27に単一のベクトルの出力を割り当てていると思います。 'str_count'の長さはdf_lettersのnrowと同じではないかもしれません – akrun

+0

私は操作をベクトル化してforループを使わないことを望んでいました。私は、次のコードが単一のドメインに対して正しい出力を生成することを知っています:str_count(df_letters $ domain [1]、letters)。私は各ドメインを増やすことを恐れており、数百万を超えるドメインリストに対しては計算上高価になるでしょう。 –

答えて

2

tabledo.callを用いて基地R代替と*bindsのカップルである:ここ

# data as a vector of strings 
sites <- c("google.com", "youtube.com") 

# get a list of counts of each letter, remove "." 
siteList <- lapply(strsplit(sites, split=""), 
        function(i) table(factor(i, levels=c(".", letters)))[-1]) 

、個々の文字を含む各要素のリストを返すstrsplit。このリストはlapplyに供給され、文字ベクトルを係数に変換した後に各文字の数をtableで計算します。この変換により、各文字がtable出力に存在することが保証されます。 [-1]は "。"を削除します。出力から。ここ

# construct data.frame 
cbind.data.frame(sites, do.call(rbind, siteList)) 
     sites a b c d e f g h i j k l m n o p q r s t u v w x y z 
1 google.com 0 0 1 0 1 0 2 0 0 0 0 1 1 0 3 0 0 0 0 0 0 0 0 0 0 0 
2 youtube.com 0 1 1 0 1 0 0 0 0 0 0 0 1 0 2 0 0 0 0 1 2 0 0 0 1 0 

は、do.call(rbind, siteList)カラム名などの文字と行の各テーブルのカウントを有する行列を返します。これはcbind.data.frameのdata.frameに変換され、ウェブサイト名も追加されます。

+0

ありがとうございます。私はlapplyとdo.callの操作の違いを学ぶ時間をとったことがないので、忘れてしまった。これは非常に役に立ちました! –

関連する問題