2

R でのデータ操作の助けが必要です。これを一連のステップとして行う長いコードがありますが、それを行うためのより短い方法を探しています。

以下に示すように、2 つの列を持つデータ フレームを次に示します。最初の列は ID で、もう 1 つはパイプで区切られたデータです。

ID  DATA
1   a
2   a|b
3   b|c
4   d|e

これを次の形式に変換する必要があります。

ID  a  b  c  d  e
1  1  0  0  0  0
2  1  1  0  0  0
3  0  1  1  0  0
4  0  0  0  1  1

私が持っている長いコードよりも、これを行う簡単な方法があることを願っています。

よろしくお願いします。

4

1 に答える 1

4

これは、提供されたデータに対して機能します。最初にデータを読み込みます:

pipdat <- read.table(stdin(),header=TRUE,stringsAsFactors=FALSE)
ID  DATA
1   a
2   a|b
3   b|c
4   d|e

# leave a blank line at the end so it stops reading

ここに行きます:

nr <- dim(pipdat)[1]
chrs <- strsplit(pipdat[,2],"[|]")
af <- unique(unlist(chrs))
whichlet <- function(a,fac) as.numeric(fac %in% a)
matrix(unlist(lapply(chrs,whichlet,af)),
        byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))

(これはより少ない行数で実行できますが、これらのステップのいくつかが何を行うかを確認すると便利です)

以下を生成します。

ID  a b c d e
  1 1 0 0 0 0
  2 1 1 0 0 0
  3 0 1 1 0 0
  4 0 0 0 1 1

あなたの投稿から、行名として ID が必要だと推測しました。最後の行が異なる必要があるデータの列にする必要がある場合。

sapplyの代わりに使用したかったのlapplyですが、最終的には目的の行列の転置になります。最後の行を次のように置き換えると機能します。

res <- t(sapply(chrs,whichlet,af))
dimnames(res) <- list(ID=1:nr,af)
res

しかし、それは遅くなるかもしれません。

---

ラインに従わない場合

matrix(unlist(lapply(chrs,whichlet,af)),
        byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))

最も内側の関数から外側に分割するだけです。

lres <- lapply(chrs,whichlet,af)
vres <- unlist(lres)
matrix(vres,byrow=TRUE,nr=nr,dimnames=list(ID=1:nr,af))

---

行名ではなくデータの列として ID が必要な場合は、次の方法があります。

lres <- lapply(chrs,whichlet,af)
vres <- unlist(lres)
cbind(ID=1:nr,matrix(vres,byrow=TRUE,nr=nr,dimnames=list(1:nr,af)))

またはあなたができる

res <- t(sapply(chrs,whichlet,af))
dimnames(res) <- list(1:nr,af)
cbind(ID=1:nr,res)
于 2013-06-04T03:23:34.807 に答える