如何迭代两个函数参数的所有组合,并在r中返回一个“n×m”矩阵
我想统计候选人在随机产生的选举中获得的第一、第二、第三等偏好的数量:如何迭代两个函数参数的所有组合,并在r中返回一个“n×m”矩阵,r,functional-programming,purrr,R,Functional Programming,Purrr,我想统计候选人在随机产生的选举中获得的第一、第二、第三等偏好的数量: library(tidyverse) library(magrittr) set.seed(42) results <- replicate(10, sample.int(5,5)) %>% t() %>% tbl_df() %>% set_colnames(c("A", "B", "C", "D", "E")) # A tibble: 10 x 5 A B C
library(tidyverse)
library(magrittr)
set.seed(42)
results <- replicate(10, sample.int(5,5)) %>%
t() %>%
tbl_df() %>%
set_colnames(c("A", "B", "C", "D", "E"))
# A tibble: 10 x 5
A B C D E
<int> <int> <int> <int> <int>
1 5 4 1 2 3
2 3 5 1 2 4
3 3 5 4 1 2
4 5 4 1 3 2
5 5 1 3 2 4
6 3 2 5 1 4
7 4 5 2 3 1
8 5 1 4 2 3
9 2 5 1 4 3
10 5 4 2 3 1
但它又回来了
[1] 0 1 1 1 0
这只是'a1''b2''c3''d4''e5'
到目前为止,我的解决方案是使用cross2获得所有组合的列表,并应用同一函数的调整版本:
count_prefs2 <- function(df, cand_round) {
df %>%
filter_at(vars(cand_round[[1]]), all_vars(. == cand_round[[2]])) %>%
nrow()
}
map_int(cross2(colnames(results), c(1:5)), count_prefs2, df = results)
[1] 0 2 4 2 2 1 1 2 4 2 3 0 1 3 3 1 3 2 1 3 5 4 1 0 0
这给了我正确的数字,但我需要将其转换为矩阵,然后是数据帧,以得到我想要的结果
map_int(cross2(colnames(results), c(1:5)), count_prefs2, df = results) %>%
matrix(nrow = 5, ncol = 5, byrow = TRUE) %>%
tbl_df() %>%
set_colnames(c("A", "B", "C", "D", "E"))
# A tibble: 5 x 5
A B C D E
<int> <int> <int> <int> <int>
1 0 2 4 2 2
2 1 1 2 4 2
3 3 0 1 3 3
4 1 3 2 1 3
5 5 4 1 0 0
对于这个问题有更优雅的解决方案吗?一个较短的base R选项使用@markus提到的stack
table(stack(df))
使用sapply的base R方法是使用表计算每列的频率,该表根据列在数据帧中可以采用的列号的最大值指定级别
n <- ncol(df)
sapply(df, function(x) table(factor(x, levels = 1:n)))
# A B C D E
#1 0 2 4 2 2
#2 1 1 2 4 2
#3 3 0 1 3 3
#4 1 3 2 1 3
#5 5 4 1 0 0
较短的base R选项使用@markus提到的stack
table(stack(df))
使用sapply的base R方法是使用表计算每列的频率,该表根据列在数据帧中可以采用的列号的最大值指定级别
n <- ncol(df)
sapply(df, function(x) table(factor(x, levels = 1:n)))
# A B C D E
#1 0 2 4 2 2
#2 1 1 2 4 2
#3 3 0 1 3 3
#4 1 3 2 1 3
#5 5 4 1 0 0
另一个baseR选项是TablesTackResults,这确实是一个方便的函数。您可以在答案中加入此选项。谢谢。所有这些建议都很好!我肯定是在以一种非常复杂的方式处理这个问题,另一个更基本的选项是tablestackresults,这确实是一个方便的函数。您可以在答案中加入此选项。谢谢。所有这些建议都很好!我肯定是以一种非常复杂的方式来解决这个问题的。tidyverse方式是gatherresults%%>%countvalue,key%%>%spreadkey,n,fill=0 tidyverse方式是gatherresults%%>%countvalue,key%%>%spreadkey,n,fill=0
purrr::map_dfr(df,~table(factor(., levels = 1:n)))
# A tibble: 5 x 5
# A B C D E
# <int> <int> <int> <int> <int>
#1 0 2 4 2 2
#2 1 1 2 4 2
#3 3 0 1 3 3
#4 1 3 2 1 3
#5 5 4 1 0 0