4

次のようなデータフレームがあります。

       a        b       c         d
ab    0        0        1         0
cd   -0.415    1.415    0         0
ef    0        0        0.0811    0.918

このテーブルを次のように変換する簡単な方法はありますか?

       a        b       c         d
ab    0        0        1         0
cd   -0.415    0        0         0
cd    0    1.415        0         0
ef    0        0        0.0811    0
ef    0        0        0         0.918

元のテーブルに 2 つ以上の数値がある場合、対応する行数に変換したいと考えています。私はそれを行う方法の手がかりを持っていないので、助けていただければ幸いです

4

5 に答える 5

4

@AnandaMahtoからいくつか借りて、リクエストに応じて溶かします。考慮してください:調べたい一意の組み合わせは左側にあります〜変数の値は右側にあります。この場合、変数名は値になりました。

library(reshape2)
mydf <- structure(list(a = c(0, -0.415, 0), b = c(0, 1.415, 0), 
                       c = c(1, 0, 0.0811), d = c(0, 0, 0.918)), 
                  .Names = c("a", "b", "c", "d"), 
                  class = "data.frame", row.names = c("ab", "cd", "ef"))
mydf$rows<- rownames(mydf)
m1<- melt(mydf, id="rows", measured= names(mydf))
m2<- dcast(m1, rows+value~..., fill=0)
m2<- m2[m2$value!=0, ]
m2$value <- NULL    

#rows      a     b      c     d
#2   ab  0.000 0.000 1.0000 0.000
#3   cd -0.415 0.000 0.0000 0.000
#5   cd  0.000 1.415 0.0000 0.000
#7   ef  0.000 0.000 0.0811 0.000
#8   ef  0.000 0.000 0.0000 0.918
于 2013-02-20T19:19:51.407 に答える
4

これは、マトリックスインデックスを使用する1つの方法です。(データはマトリックスに変換されるため、例のように、データが1つのタイプである方が適切です。)

reformat.dat <- function(dat) {
  tdat <- t(dat)
  nz <- tdat != 0
  i <- col(tdat)[nz]
  j <- row(tdat)[nz]
  out <- matrix(0, sum(nz), ncol(dat))
  out[cbind(seq_len(sum(nz)), j)] <- tdat[nz]
  rownames(out) <- rownames(dat)[i]
  colnames(out) <- colnames(dat)
  out
}

reformat.dat(dat)
#         a     b      c     d
# ab  0.000 0.000 1.0000 0.000
# cd -0.415 0.000 0.0000 0.000
# cd  0.000 1.415 0.0000 0.000
# ef  0.000 0.000 0.0811 0.000
# ef  0.000 0.000 0.0000 0.918
于 2013-02-20T12:36:28.380 に答える
2

を使用した簡単なソリューションを次に示しdiagます。

o <- apply(df, 1, function(x) {
    t <- diag(x)
    colnames(t) <- names(x)
    t <- t[rowSums(t == 0) != length(x), ,drop = FALSE]
    t
})
ids <- rep(names(o), sapply(o, nrow))
o <- do.call(rbind, o)
row.names(o) <- ids

#         a     b      c     d
# ab  0.000 0.000 1.0000 0.000
# cd -0.415 0.000 0.0000 0.000
# cd  0.000 1.415 0.0000 0.000
# ef  0.000 0.000 0.0811 0.000
# ef  0.000 0.000 0.0000 0.918

これはmatrix. as.data.frame(.)が必要な場合に使用しますdata.frame

于 2013-02-20T14:20:17.350 に答える
1

これは 1 つのアプローチですが、行名を修正するためにいくつかの表面的な変更をフォローアップする必要があります。

再現可能な形式のデータ:

mydf <- structure(list(a = c(0, -0.415, 0), b = c(0, 1.415, 0), 
                       c = c(1, 0, 0.0811), d = c(0, 0, 0.918)), 
                  .Names = c("a", "b", "c", "d"), 
                  class = "data.frame", row.names = c("ab", "cd", "ef"))

NAゼロをsに置き換えます。

mydf[mydf == 0] <- NA

stackあなたdata.frameはそれを「長い」ものにしますdata.frame

mydf1 <- data.frame(Rows = rownames(mydf), stack(mydf))

「行」の一意の値を生成します

mydf1$Rows <- make.unique(as.character(mydf1$Rows))
# Let's see what we have so far....
mydf1
#    Rows  values ind
# 1    ab      NA   a
# 2    cd -0.4150   a
# 3    ef      NA   a
# 4  ab.1      NA   b
# 5  cd.1  1.4150   b
# 6  ef.1      NA   b
# 7  ab.2  1.0000   c
# 8  cd.2      NA   c
# 9  ef.2  0.0811   c
# 10 ab.3      NA   d
# 11 cd.3      NA   d
# 12 ef.3  0.9180   d

ここで、xtabs探している出力を取得するために使用します。as.data.frame.matrixが必要な場合はラップし、data.frame必要に応じて行名をクリーンアップします。

as.data.frame.matrix(xtabs(values ~ Rows + ind, mydf1))
#           a     b      c     d
# ab.2  0.000 0.000 1.0000 0.000
# cd   -0.415 0.000 0.0000 0.000
# cd.1  0.000 1.415 0.0000 0.000
# ef.2  0.000 0.000 0.0811 0.000
# ef.3  0.000 0.000 0.0000 0.918
于 2013-02-20T12:43:25.330 に答える
-1

あなたが正確に求めているもののエレガントなバージョンはないと思いますがmeltreshape2代わりに使用できるかもしれませんか?行/列のペアごとに1行が表示されます。

> library(reshape2) 
> # add row names as column
> df <- cbind(df, names=rownames(df))
> df <- melt(df,id.var="names")
Using  as id variables
> df[df$value != 0,]
   names variable   value
2     cd        a -0.4150
5     cd        b  1.4150
7     ab        c  1.0000
9     ef        c  0.0811
12    ef        d  0.9180
于 2013-02-20T12:10:56.853 に答える