最简单的方法来根据其符号交叉表格

时间:2017-10-11 11:37:07

标签: r dplyr crosstab tidyr tidyverse

我有一个刺痛,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

简单方式获取此结果的任何建议?

3 个答案:

答案 0 :(得分:4)

另一种方法是使用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

答案 1 :(得分:3)

另一种方法是,根据符号拆分变量,然后调用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

答案 2 :(得分:1)

从你的问题中得出:

> 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
>