map_dfr 将数据框输入转换为列

map_dfr converting data frame input to column

我正在尝试使用以下函数遍历数据框和return每一行的计数:

library(dplyr)
library(tidyr)
row_freq <- function(df_input,row_input){
  print(df_input)
  vec <- unlist(df_input %>% 
                  select(-1) %>% 
                  slice(row_input), use.names = FALSE)
  r <- data.frame(table(vec)) %>% 
    pivot_wider(values_from = Freq, names_from = vec)
  return(r)
}

如果我使用数据框中的单行,这很好用:

sample_df <- data.frame(id = c(1,2,3,4,5), obs1 = c("A","A","B","B","B"),
                        obs2 = c("B","B","C","D","D"), obs3 = c("A","B","A","D","A"))
row_freq(sample_df, 1)

  id obs1 obs2 obs3
1  1    A    B    A
2  2    A    B    B
3  3    B    C    A
4  4    B    D    D
5  5    B    D    A
# A tibble: 1 × 2
      A     B
  <int> <int>
1     2     1

但是当使用 purrr::map_dfr 遍历行时,它似乎将 df_input 减少到仅 id 列而不是使用整个数据框作为参数,我觉得这很奇怪:

purrr::map_dfr(sample_df, row_freq, 1:5)
[1] 1 2 3 4 5
 Error in UseMethod("select") : 
no applicable method for 'select' applied to an object of class "c('double', 'numeric')"

我正在寻求有关以下方面的帮助:1) 为什么会发生这种情况,2) 如何修复它,以及 3) 可能已经执行我正在尝试做的事情的任何替代方法或功能高效的方式。

如果我们不使用命名参数传递,请正确指定参数的顺序

purrr::map_dfr(1:5, ~ row_freq(sample_df, .x))

-输出

# A tibble: 5 × 4
      A     B     C     D
  <int> <int> <int> <int>
1     2     1    NA    NA
2     1     2    NA    NA
3     1     1     1    NA
4    NA     1    NA     2
5     1     1    NA     1

或者使用命名参数

purrr::map_dfr(df_input = sample_df, .f = row_freq, .x = 1:5)

-输出

# A tibble: 5 × 4
      A     B     C     D
  <int> <int> <int> <int>
1     2     1    NA    NA
2     1     2    NA    NA
3     1     1     1    NA
4    NA     1    NA     2
5     1     1    NA     1

原因是map第一个参数是.x

map(.x, .f, ...)

如果我们提供 'sample_df' 作为参数,它将 .x 作为 sample_df 并遍历数据列(如 data.frame/tibble/data.table - 单位是列,因为这些 list 具有附加属性)