dplyr汇总用户定义函数的多个输入值

问题描述

我有一个数据框df,我想在其中满足col1中条件的col2中唯一值的比例。

set.seed(137)
df <- data.frame(col1 = sample(LETTERS,100,TRUE),col2 = sample(-75:75,col3 = sample(-75:75,TRUE))

df$col2[c(23,48,78)] <- NA
df$col3[c(37,68,81)] <- NA

例如,我想在col1中找到所有在col2-10范围内的10中的唯一值。

df %>%  
  mutate(unqCol1 = n_distinct(col1)) %>% 
  group_by(col1) %>% 
  mutate(freq = sum(between(col2,-10,10),na.rm = TRUE)) %>% 
  filter(freq > 0) %>% distinct(col1,unqCol1) %>% 
  ungroup() %>%  
  summarise(nrow(.)/unqCol1) %>% 
  unique()

结果为:

# A tibble: 1 x 1
  `nrow(.)/unqCol1`
              <dbl>
1             0.423

尽管上述代码段不是一种有效的方法,但我还是尝试通过单个管道命令来实现结果,并且为我提供了正确的输出(重写上面的代码很容易理解)。我已使用基本R方法重新确认了输出:

length(unique(df$col1[df$col2 >= -10 & df$col2 <= 10 & !is.na(df$col2)]))/length(unique(df$col1))

我想在函数中重写上面的dplyr代码,以便可以使用范围的n的多个值(此处为n=10)复制它(也适用于多列)。这可能吗?还是应该像 apply-family 这样的想法在代码本身内传递多个值(不带功能)?

解决方法

您已经注意到,您的(dplyr)代码过于复杂。您可以在不对数据进行分组的情况下计算感兴趣的比例:

df %>% 
  tidyr::drop_na() %>%
  filter(between(col2,-10,10)) %>% 
  summarize(prop = n_distinct(col1) / n_distinct(df$col1))

计算比例的函数是:

my_summary <- function(df,...) {
   df %>% 
     tidyr::drop_na() %>%
     filter(...) %>% 
     summarize(
       prop = n_distinct(col1) / n_distinct(df$col1)
     )
}

例如

> my_summary(df,between(col2,10))
       prop
1 0.4230769

给出问题的比例。

编辑

您可以向量化my_summary()并使用outer()来获得coln的组合的比例矩阵:

my_summary <- function(col,n) {
  df %>% 
    tidyr::drop_na() %>%
    filter(between(!!as.name(col),-n,n)) %>% 
    summarize(
      prop = n_distinct(col1) / n_distinct(df$col1)
    )
}
my_summary_v <- Vectorize(my_summary)
> outer(c("col2","col3"),c(10,20,30),my_summary_v)
     [,1]      [,2]      [,3]     
[1,] 0.4230769 0.5384615 0.6538462
[2,] 0.4230769 0.6538462 0.6923077

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...