跨多个列,计算对的实例
Across several columns, count instances of pairs
我想计算几列中的对数。也就是说,对于超过两列,计算特定值对在同一行中出现的次数。
假设我问一些人是否喜欢不同种类的食物,他们可以回答“是”或“否”。我最终得到了这个数据集:
foods <-
data.frame(
fruit = c("yes", "yes", "no"),
veg = c("yes", "yes", "yes"),
meat = c("yes", "no", "yes")
)
foods
我想计算任意两种食物获得“是”的次数。我希望以这样的方式结束:
desired <-
data.frame(
pair.1 = c("fruit", "fruit", "veg"),
pair.2 = c("veg", "meat", "meat"),
Freq = c(2, 1, 2)
)
desired
这也可行:
desired.2 <-
data.frame(
pair. = c("fruit, veg", "fruit, meat", "veg, meat"),
Freq = c(2, 1, 2)
)
desired.2
如果可能的话,我希望我可以使用一种解决方案最终对 3、4 等的组合执行相同的操作(我的实际数据有 3 列以上)。有什么好的解决方案,最好使用 dplyr?
预先感谢您的帮助!
一个dplyr
和purrr
的解决方案可以是:
map_dfr(.x = combn(names(foods), 2, simplify = FALSE),
~ foods %>%
select(.x) %>%
summarise(pair_1 = .x[1],
pair_2 = .x[2],
n = sum(rowSums(select(., everything()) == "yes") == 2)))
pair_1 pair_2 n
1 fruit veg 2
2 fruit meat 1
3 veg meat 2
如果你想要更通用的东西:
fun <- function(x) {
map_dfr(.x = combn(names(foods), x, simplify = FALSE),
~ foods %>%
select(.x) %>%
summarise(pairs = paste(.x, collapse = " "),
n = sum(rowSums(select(., everything()) == "yes") == x)))
}
fun(2)
pairs n
1 fruit veg 2
2 fruit meat 1
3 veg meat 2
您可以使用combn
,即
combn(names(foods), 2, FUN = function(i){i1 <- foods[i]; sum(i1[1] == i1[2])})
#[1] 2 1 2
对于成对的人,听起来您正在寻找 crossprod
:
crossprod(foods == "yes")
# fruit veg meat
# fruit 2 2 1
# veg 2 3 2
# meat 1 2 2
注意上面结果的upper.tri
或lower.tri
。
如果我们将结果视为 table
,我们可以将其包装在 data.frame
中并仅提取那些特定的对:
x <- crossprod(foods == "yes")
data.frame(as.table(x))[lower.tri(x), ]
# Var1 Var2 Freq
# 2 veg fruit 2
# 3 meat fruit 1
# 6 meat veg 2
我想计算几列中的对数。也就是说,对于超过两列,计算特定值对在同一行中出现的次数。
假设我问一些人是否喜欢不同种类的食物,他们可以回答“是”或“否”。我最终得到了这个数据集:
foods <-
data.frame(
fruit = c("yes", "yes", "no"),
veg = c("yes", "yes", "yes"),
meat = c("yes", "no", "yes")
)
foods
我想计算任意两种食物获得“是”的次数。我希望以这样的方式结束:
desired <-
data.frame(
pair.1 = c("fruit", "fruit", "veg"),
pair.2 = c("veg", "meat", "meat"),
Freq = c(2, 1, 2)
)
desired
这也可行:
desired.2 <-
data.frame(
pair. = c("fruit, veg", "fruit, meat", "veg, meat"),
Freq = c(2, 1, 2)
)
desired.2
如果可能的话,我希望我可以使用一种解决方案最终对 3、4 等的组合执行相同的操作(我的实际数据有 3 列以上)。有什么好的解决方案,最好使用 dplyr?
预先感谢您的帮助!
一个dplyr
和purrr
的解决方案可以是:
map_dfr(.x = combn(names(foods), 2, simplify = FALSE),
~ foods %>%
select(.x) %>%
summarise(pair_1 = .x[1],
pair_2 = .x[2],
n = sum(rowSums(select(., everything()) == "yes") == 2)))
pair_1 pair_2 n
1 fruit veg 2
2 fruit meat 1
3 veg meat 2
如果你想要更通用的东西:
fun <- function(x) {
map_dfr(.x = combn(names(foods), x, simplify = FALSE),
~ foods %>%
select(.x) %>%
summarise(pairs = paste(.x, collapse = " "),
n = sum(rowSums(select(., everything()) == "yes") == x)))
}
fun(2)
pairs n
1 fruit veg 2
2 fruit meat 1
3 veg meat 2
您可以使用combn
,即
combn(names(foods), 2, FUN = function(i){i1 <- foods[i]; sum(i1[1] == i1[2])})
#[1] 2 1 2
对于成对的人,听起来您正在寻找 crossprod
:
crossprod(foods == "yes")
# fruit veg meat
# fruit 2 2 1
# veg 2 3 2
# meat 1 2 2
注意上面结果的upper.tri
或lower.tri
。
如果我们将结果视为 table
,我们可以将其包装在 data.frame
中并仅提取那些特定的对:
x <- crossprod(foods == "yes")
data.frame(as.table(x))[lower.tri(x), ]
# Var1 Var2 Freq
# 2 veg fruit 2
# 3 meat fruit 1
# 6 meat veg 2