Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 将数值转换为二进制(0/1)_R_Dataframe_Matrix_Binary - Fatal编程技术网

R 将数值转换为二进制(0/1)

R 将数值转换为二进制(0/1),r,dataframe,matrix,binary,R,Dataframe,Matrix,Binary,我有一个数据框,里面有不同人群的不同种类水果的计数。如下 apple banana orange Tim 3 0 2 Tom 0 1 1 Bob 1 2 2 apple banana orange Tim 1 0 1 Tom 0 1 1 Bob 1 1 1 如何将其转换为二进制矩

我有一个数据框,里面有不同人群的不同种类水果的计数。如下

    apple  banana  orange
Tim     3       0       2
Tom     0       1       1
Bob     1       2       2
    apple  banana  orange
Tim     1       0       1
Tom     0       1       1
Bob     1       1       1
如何将其转换为二进制矩阵,即,如果一个人至少有一个水果,无论他有多少个,那么I记录1,如果没有,则记录0。如下

    apple  banana  orange
Tim     3       0       2
Tom     0       1       1
Bob     1       2       2
    apple  banana  orange
Tim     1       0       1
Tom     0       1       1
Bob     1       1       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)))

使用可以使用
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
>测向
苹果香蕉橙
[1,]     3      0      2
[2,]     0      1      1
[3,]     1      2      2
>ifelse(df>0,1,0)
苹果香蕉橙
[1,]     1      0      1
[2,]     0      1      1
[3,]     1      1      1

这是您的
数据。帧

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"))
更新 我不知道睡前快速发帖会产生什么效果,但讨论本身很有趣,所以我想在这里总结一下:

我本能地认为,在R中的
TRUE
FALSE
下面是数字
1
0
。如果您尝试(一种不太好的方法)检查等价性,例如
1==TRUE
0==FALSE
,您将得到
TRUE
。我的捷径(比正确的,或者至少在概念上更正确的方法花费了更多的时间)是将
0
添加到我的
TRUE
s和
FALSE
s中,因为我知道R会强制逻辑向量为数值

正确的,或者至少是更合适的方法是使用
作为.numeric
转换输出(我认为@JoshO'Brien打算这样写)。但是不幸的是,这会删除输入的维度属性,因此您需要将结果向量重新转换为矩阵,结果表明,与我在回答中添加的
0
相比,该矩阵仍然更快

在阅读了评论和批评之后,我想我应该再添加一个选项——使用
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
x
>pippo
人苹果香蕉橙
1分时10分2秒
2汤姆01
3鲍勃1 2

>cols lappy(cols,function(x){pippo[,x]我通常使用这种方法:

df[df > 0] = 1

你的对象是矩阵还是数据框?如果它是一个包含所有数字信息的数据框,你可以将它强制为一个带有
as.matrix
的矩阵。它是一个带有标题的数据框,为什么这比
ifelse
好?(我没有问,因为我建议这样做,只是好奇)@ChinmayPatil——首先,Ananda的解决方案运行速度比
ifelse()
版本快3-4倍。(FWIW
as.logical(as.matrix(x)>0)
是他的解决方案的两倍。)这是我用来运行一些时间测试的data.frame:
x@JoshO'Brien谢谢你的回复。我也检查了同样的事情。事实确实如此。:)@JoshO'Brien,谢谢。你是说
as.numeric
,对吗?我很快就会更新我的答案。@ChinmayPatil,我已经用一些基准和进一步的思考更新了我的答案。