7

さまざまな人のさまざまな種類の果物の数を含むデータ フレームがあります。以下のように

    apple  banana  orange
Tim     3       0       2
Tom     0       1       1
Bob     1       2       2

どうすればそれをバイナリ行列に変更できますか。つまり、人が果物を少なくとも 1 つ持っている場合、何個持っていても、I は 1 を記録し、そうでない場合は 0 を記録します。以下のように

    apple  banana  orange
Tim     1       0       1
Tom     0       1       1
Bob     1       1       1
4

5 に答える 5

20

ここにあなたのdata.frame

x <- structure(list(apple = c(3L, 0L, 1L), banana = 0:2, orange = c(2L, 
1L, 2L)), .Names = c("apple", "banana", "orange"), class = "data.frame", row.names = c("Tim", 
"Tom", "Bob"))

そしてあなたのマトリックス:

as.matrix((x > 0) + 0)
    apple banana orange
Tim     1      0      1
Tom     0      1      1
Bob     1      1      1

アップデート

就寝前の簡単な投稿で議論が生まれるとは思いもしませんでし 、議論自体は非常に興味深いので、ここに要約したいと思います。

私の本能は、Rの aTRUEとの下に数字とがあるという事実を単純に理解することでした。またはなどの等価性をチェックしようとすると (あまり良い方法ではありません)、が得られます。R が論理ベクトルを数値に強制することがわかっているので、私の近道の方法 (正しい方法、または少なくとも概念的に正しい方法より時間がかかることが判明) は、 と に追加するだけでした。FALSE101 == TRUE0 == FALSETRUE0TRUEFALSE

正しい、または少なくともより適切な方法は、を使用して出力を変換することas.numericです(@ JoshO'Brienが意図したものだと思います)。しかし....残念ながら、それは入力の次元属性を削除するため、結果のベクトルをマトリックスに再変換する必要があります。これは、回答で行ったように追加するよりも高速です。0

コメントと批判を読んだ後、もう 1 つのオプションを追加すると思いました。apply列をループしてas.numericアプローチを使用することです。これは、マトリックスを手動で再作成するよりも遅くなりますが、論理比較に追加するよりはわずかに高速です。0

x <- data.frame(replicate(1e4,sample(0:1e3)))
library(rbenchmark)
benchmark(X1 = {
            x1 <- as.matrix((x > 0) + 0)
          },
          X2 = {
            x2 <- apply(x, 2, function(y) as.numeric(y > 0))
          },
          X3 = {
            x3 <- as.numeric(as.matrix(x) > 0)
            x3 <- matrix(x3, nrow = 1001)
          },
          X4 = {
            x4 <- ifelse(x > 0, 1, 0)
          },
          columns = c("test", "replications", "elapsed", 
                      "relative", "user.self"))
#   test replications elapsed relative user.self
# 1   X1          100 116.618    1.985   110.711
# 2   X2          100 105.026    1.788    94.070
# 3   X3          100  58.750    1.000    46.007
# 4   X4          100 382.410    6.509   311.567

all.equal(x1, x2, check.attributes=FALSE)
# [1] TRUE
all.equal(x1, x3, check.attributes=FALSE)
# [1] TRUE
all.equal(x1, x4, check.attributes=FALSE)
# [1] TRUE

議論してくれてありがとう!

于 2013-01-25T16:57:54.137 に答える
6

私は通常、このアプローチを使用します。

df[df > 0] = 1
于 2016-08-09T21:13:13.917 に答える
4

使用できますifelse。マトリックスとデータフレームの両方で機能するはずですが、結果の値はマトリックスになります

> df <- cbind(aaple = c(3, 0 , 1), banana = c(0, 1, 2), orange = c(2, 1, 2))
> df
     aaple banana orange
[1,]     3      0      2
[2,]     0      1      1
[3,]     1      2      2

> ifelse(df>0, 1, 0)
     aaple banana orange
[1,]     1      0      1
[2,]     0      1      1
[3,]     1      1      1
于 2013-01-25T16:53:32.820 に答える
1

比較を使用してください:

d = t(matrix(c(3,0,2,0,1,1,1,2,2), 3))
d > 0
t(matrix(as.numeric(d>0), ncol(d)))
于 2013-01-25T16:48:23.027 に答える
0
> pippo
  person apple banana orange
1    Tim     1      0      2
2    Tom     0      1      1
3    Bob     1      2      2
> cols <- c("apple", "banana", "orange")
> lapply(cols, function(x) {pippo[,x] <<- as.numeric(pippo[,x] >= 1)})
于 2013-01-25T16:58:16.740 に答える