10

我有以下数据框:

a    b     c     d     e
TRUE TRUE FALSE  TRUE  TRUE
FALSE TRUE  TRUE  TRUE FALSE
TRUE TRUE FALSE  TRUE  TRUE
TRUE TRUE  TRUE FALSE  TRUE
TRUE TRUE  TRUE  TRUE  TRUE
TRUE TRUE  TRUE  TRUE  TRUE

我想使用以下逻辑创建一个额外的列,比如 f:

TRUE = If all the columns in the corresponding row are all TRUE or all FALSE.
FALSE = if one or more colums differ from the other columns in the corresponding row.

在这个例子中,输出将是

a    b     c     d     e     f
TRUE TRUE FALSE  TRUE  TRUE  FALSE
FALSE TRUE  TRUE  TRUE FALSE  FALSE
TRUE TRUE FALSE  TRUE  TRUE  FALSE
TRUE TRUE  TRUE FALSE  TRUE  FALSE
TRUE TRUE  TRUE  TRUE  TRUE  TRUE
TRUE TRUE  TRUE  TRUE  TRUE  TRUE
4

4 回答 4

11

用这个:

DF$f <- apply(DF, 1, function(x)(all(x) || all(!x)))

其中“DF”是您的数据框。

于 2013-09-09T23:40:37.893 回答
7

logical或者,利用值只是0s 和1s 用于算术的事实:

rowMeans(dat) %in% 0:1
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE
于 2013-09-10T00:10:00.940 回答
4

@Ferdinand.kraft 提供的答案是正确的,并且是最易读的答案,但是要使用 hack rowSums

DF$f <- rowSums(DF) %in% c(0, 5)

这在我的系统上快了大约 33%:

> system.time(replicate(10000, apply(DF, 1, function(x) {all(x) || all(!x)})))
   user  system elapsed 
   3.11    0.00    3.12 

> system.time(replicate(10000, rowSums(DF) %in% c(0, 5)))
   user  system elapsed 
   1.95    0.00    1.95

但是,正如我所说,这有点像 hack,可能只应在速度很重要时使用。

于 2013-09-10T00:10:25.243 回答
3

就速度而言,这是相当快的:

do.call(pmin.int,dat)==do.call(pmax.int,dat)

速度测试:

microbenchmark(
    allorall=apply(dat, 1, function(x) {all(x) || all(!x)}),
    rmeans=rowMeans(dat) %in% 0:1,
    rsum=rowSums(dat) %in% c(0, 5),
    minmax=do.call(pmin.int,dat)==do.call(pmax.int,dat)
)

Unit: microseconds
     expr     min       lq   median       uq      max neval
 allorall 278.598 287.7760 301.8145 340.9585  722.410   100
   rmeans 178.174 182.4925 191.6715 205.9790  471.888   100
     rsum 177.093 182.7625 188.4315 202.4695 1796.304   100
   minmax  17.278  19.9775  22.1375  26.1870   42.115   100

为什么没有一个prange

于 2013-09-17T00:42:12.463 回答