计算二元变量之间的重叠

问题描述 投票:0回答:5

我正在尝试计算有多少人参加不同的运动组合。我知道如何计算和绘制相关性,但我想获得每个组合组中有多少人的实际数字。

这是我的数据的简化演示。

1
表示特定的人从事特定的运动,
0
表示她不从事特定的运动。

    sports_example <- tibble(
      name = c(
        "Scarlett",
        "Heather",
        "Sarah",
        "Anna",
        "Emma",
        "Charlotte",
        "Cheryl"
      ),
      hockey = c(1L, 1L, 1L, 1L, 0L, 1L, 1L),
      basketball = c(0L, 1L, 1L, 0L, 1L, 1L, 0L),
      track = c(1L, 1L, 1L, 0L, 1L, 0L, 1L),
      football = c(0L, 1L, 0L, 0L, 0L, 0L, 0L)
    )

使用下面的代码,我可以计算不同运动之间的相关性。我可以看出,曲棍球与篮球的共同球员比足球更多。但我想计算有多少运动员同时打曲棍球和篮球(本例中为 3 名)。有没有一种简单的算法来计算重叠?我的真实数据集有几十列,因此我的一次性代码无法删除它(例如

nrow(filter(sports_example, hockey + basketball == 2))
)。

sports_example %>% 
  select(-name) %>% 
  cor() %>% 
  corrgram::corrgram(upper.panel = NULL)

r correlation
5个回答
2
投票

对于成对结果,您可以计算二元变量的矩阵叉积,然后将上三角形和对角线设置为零,以便我们可以过滤以仅保留唯一的对。

res <- crossprod(as.matrix(sports_example[-1]))
res[upper.tri(res, diag = TRUE)] <- 0
subset(as.data.frame.table(res), Freq > 0)

         Var1       Var2 Freq
2  basketball     hockey    3
3       track     hockey    4
4    football     hockey    1
7       track basketball    3
8    football basketball    1
12   football      track    1

1
投票

我建议您采用下一种方法,您可以确定所有玩家会发生什么:

library(reshape2)
library(tibble)
library(dplyr)

#Data
sports_example <- tibble(
  name = c(
    "Scarlett",
    "Heather",
    "Sarah",
    "Anna",
    "Emma",
    "Charlotte",
    "Cheryl"
  ),
  hockey = c(1L, 1L, 1L, 1L, 0L, 1L, 1L),
  basketball = c(0L, 1L, 1L, 0L, 1L, 1L, 0L),
  track = c(1L, 1L, 1L, 0L, 1L, 0L, 1L),
  football = c(0L, 1L, 0L, 0L, 0L, 0L, 0L)
)

#Reshape
Melted <- melt(sports_example,id.vars = 'name')

重塑后,您可以使用

dplyr
函数进行分组和聚合:

#Now filter and compute
Melted %>% group_by(name) %>% filter(variable %in% c('hockey','basketball')) %>% 
  summarise(N=sum(value))

这将导致:

# A tibble: 7 x 2
  name          N
  <chr>     <int>
1 Anna          1
2 Charlotte     2
3 Cheryl        1
4 Emma          1
5 Heather       2
6 Sarah         2
7 Scarlett      1

然后你可以添加一个新的过滤器来达到你想要的:

#Now filter and compute 2
Melted %>% group_by(name) %>% filter(variable %in% c('hockey','basketball')) %>% 
  summarise(N=sum(value)) %>% filter(N==2)

输出:

# A tibble: 3 x 2
  name          N
  <chr>     <int>
1 Charlotte     2
2 Heather       2
3 Sarah         2

然后,您还可以识别玩家和您想要的号码。


1
投票

怎么样

count()

count(sports_example, hockey, basketball)
##   hockey basketball     n
##    <int>      <int> <int>
## 1      0          1     1
## 2      1          0     3
## 3      1          1     3

或者

(count(sports_example, hockey, basketball) 
   %>% filter(hockey==1, basketball==1)
   %>% pull(n)
)

base-R 版本会是这样的

with(sports_example, as.data.frame(table(hockey,basketball)))

1
投票

以长格式获取数据,仅保留

value = 1
的行,为每个
name
count
创建配对组合。

library(dplyr)

sports_example %>%
  tidyr::pivot_longer(cols = -name, names_to = 'col') %>%
  filter(value == 1) %>%
  group_by(name) %>%
  summarise(val = if(n() > 1) combn(col, 2, function(x) 
                     sort(toString(x))) else col) %>%
  ungroup %>%
  count(val)

#  val                      n
#  <chr>                <int>
#1 basketball, football     1
#2 basketball, track        3
#3 hockey                   1
#4 hockey, basketball       3
#5 hockey, football         1
#6 hockey, track            4
#7 track, football          1

此答案适用于

dplyr
> 1.0.0,它允许在
summarise
中返回多行。


0
投票

您可以矢量化:

(sports_example$hockey & sports_example$basketball) %>% sum
© www.soinside.com 2019 - 2024. All rights reserved.