根据符号越过 table 刺的最简单方法
Simplest way to cross table a sting based on its sign
我有一个刺 x
,我想与它自己交叉,即创建一个交叉 table,基于 said 的值为正或负(它永远不会 == 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
对于获得此结果的简单方法有何建议?
根据您的问题得出:
> 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
>
另一种方法是使用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
s 作为输入,所以你可以这样做:
with(foo, table(split(x, sign(x))))
# 1
#-1 1 3
# -3 0 2
# -2 1 0
如果您需要让级别按绝对值排序,您可以将 x
("for each sign") 的每个部分定义为 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
我有一个刺 x
,我想与它自己交叉,即创建一个交叉 table,基于 said 的值为正或负(它永远不会 == 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
对于获得此结果的简单方法有何建议?
根据您的问题得出:
> 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
>
另一种方法是使用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
s 作为输入,所以你可以这样做:
with(foo, table(split(x, sign(x))))
# 1
#-1 1 3
# -3 0 2
# -2 1 0
如果您需要让级别按绝对值排序,您可以将 x
("for each sign") 的每个部分定义为 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