r语言 - 根据其标志交叉表刺的最简单方法



我有一个刺痛,x,我想与它自己交叉,即创建一个交叉表,基于所述为正或负的值(它永远不会== 0)。

即,假设我的数据看起来像这样

foo <- tibble(x = c(-3L, 3L, -3L, 3L, -2L, 1L))
foo
#> # A tibble: 6 x 1
#>       x
#>   <int>
#> 1    -3
#> 2     3
#> 3    -3
#> 4     3
#> 5    -2
#> 6     1

我正在尝试这样的事情

with(foo, table(x, with(foo, x > 0)))
#> x    FALSE TRUE
#>   -3     2    0
#>   -2     1    0
#>   1      0    1
#>   3      0    2
library(dplyr) # install.packages(c("dplyr"), dependencies = TRUE)
library(tidyr) # install.packages(c("tidyr"), dependencies = TRUE)
foo %>% 
group_by(sign(x) == 1) %>%
tally() %>%
spread(x, n, fill = 0)

但我想要的是

neg <- unlist(subset(foo, x < 0))
pos <- unlist(subset(foo, x > 0))
# order `neg` 
neg <- factor(ordered(as.factor(neg)), levels=rev(levels(ordered(as.factor(neg)))))
table(neg, pos)
#>     pos
#> neg  1 3
#>   -2 1 0
#>   -3 0 2

关于获得此结果的简单方法的任何建议?

另一种方法是使用 xtabs 。输出(非常)丑陋但正确。

xtabs(~ x[x > 0] + x[x < 0], data = foo)
#        x[x < 0]
#x[x > 0] -3 -2
#       1  0  1
#       3  2  0

编辑。
回到OP的原始解决方案,以下工作。

with(foo, table(pos = x[x > 0], neg = x[x < 0]))
#   neg
#pos -3 -2
#  1  0  1
#  3  2  0

另一种方法是,根据变量的符号拆分变量,然后调用table

编辑:

如@eddi所述,实际上table可以将list作为输入进行处理,因此您可以执行以下操作:

with(foo, table(split(x, sign(x))))
#    1
#-1   1 3
#  -3 0 2
#  -2 1 0

如果需要按绝对值对级别进行排序,则可以将x的每个部分("对于每个符号")定义为具有有序级别(根据绝对值)的factor

with(foo, table(lapply(split(x, sign(x)), 
                       function(sp_x) factor(sp_x, levels=unique(sp_x[order(abs(sp_x))]), ordered=TRUE))))
 #   1
#-1   1 3
#  -2 1 0
#  -3 0 2

老:

do.call(table, split(foo$x, sign(foo$x))) 
# or with(foo, do.call(table, split(x, sign(x))))
#    1
#-1   1 3
#  -3 0 2
#  -2 1 0

从你的问题中得出:

> foo <- data.frame(x = c(-3L, 3L, -3L, 3L, -2L, 1L))
> 
> table(pos = foo[foo$x>0,],neg = foo[foo$x<0,])
   neg
pos -3 -2
  1  0  1
  3  2  0
> 

最新更新