私はカテゴリ変数を持つデータフレームを持っていますの文字列を可変長でリストしています(これは重要ではないのでこの質問はthisまたはthis)、例えば:R:リストのカテゴリ変数*に基づいてダミー変数を作成する*
df <- data.frame(x = 1:5)
df$y <- list("A", c("A", "B"), "C", c("B", "D", "C"), "E")
df
x y 1 1 A 2 2 A, B 3 3 C 4 4 B, D, C 5 5 E
そして所望の形態がdf$y
、すなわち内のどこにでも見られた各一意の文字列のためのダミー変数である:
data.frame(x = 1:5, A = c(1,1,0,0,0), B = c(0,1,0,1,0), C = c(0,0,1,1,0), D = c(0,0,0,1,0), E = c(0,0,0,0,1))
x A B C D E 1 1 1 0 0 0 0 2 2 1 1 0 0 0 3 3 0 0 1 0 0 4 4 0 1 1 1 0 5 5 0 0 0 0 1
この単純なアプローチは動作します:
> uniqueStrings <- unique(unlist(df$y))
> n <- ncol(df)
> for (i in 1:length(uniqueStrings)) {
+ df[, n + i] <- sapply(df$y, function(x) ifelse(uniqueStrings[i] %in% x, 1, 0))
+ colnames(df)[n + i] <- uniqueStrings[i]
+ }
、それは非常に醜い怠惰とビッグデータフレームと遅いですが。
提案がありますか? tidyverse
から何か気に入っていますか?
更新:以下の3つのアプローチがあります。私はリアルデータセットの私の(Windows 7、32GBのRAM)ラップトップ上のsystem.time
を使用してそれらをテストしました。1M行からなり、各行は1〜4文字の長さのリスト(約350個の一意の文字列値)ディスク上に。したがって、予想される結果は、1M x 350のデータフレームです。tidyverse
(@Sotos)とbase
(@ joel.wilson)のアプローチは、Rを再起動しなければならないほど長くかかりました。しかし、qdapTools
(@akrun)のアプローチは素晴らしい:
> system.time(res1 <- mtabulate(varsLists))
user system elapsed
47.05 10.27 116.82
これが私が受け入れる方法です。
または 'data.frame(X = DFの$ Xを、T(sapply(DFの$ yを、関数(L){テーブル(因子(L、レベル=文字[1:5] ))}))) ' – alistaire
@ letterista多分' LETTERS [1:5] 'の代わりに' levels = unique(unlist(df $ y)) 'でしょうか? – Sotos
@Sotos私はそれを持っていましたが、これは計算が少ないと考えました。最高のルートは、別の変数としてそれを格納することですが、それは2行目を必要とするでしょう... – alistaire