我有一个刺痛,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
对简单方式获取此结果的任何建议?
答案 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
>