我正在尝试应用基于整洁的方法,或者至少是一种整洁的解决方案,以将自定义函数应用于数据帧中某个因子的级别。
考虑以下测试数据集:
df <- tibble(LINE=rep(c(1,2),each=6), FOUND=c(1,1,1,0,1,1,0,0,1,0,0,1))
# LINE FOUND
# <dbl> <dbl>
# 1 1 1
# 2 1 1
# 3 1 1
# 4 1 0
# 5 1 1
# 6 1 1
# 7 2 0
# 8 2 0
# 9 2 1
#10 2 0
#11 2 0
#12 2 1
我想知道例如按LINE因子级别找到的结果的比例(例如FOUND == 1)。现在,我正在使用以下代码,但是我实际上是在尝试更清洁的方法。
# This is the function to calculate the proportion "found"
get_prop <- function (data) {
tot <- data %>% nrow()
found <- data %>% dplyr::filter(FOUND==1) %>% nrow
found / tot
}
# This is the code to generate the expected result
lines <- df$LINE %>% unique %>% sort
v_line <- vector()
v_prop <- vector()
for (i in 1:length(lines)) {
tot <- df %>% dplyr::filter(LINE==lines[i])
v_line[i] <- lines[i]
v_prop[i] <- get_prop(tot)
}
df_line = data.frame(LINE = v_line, CALL = v_prop)
我希望下面的方法能起作用,但是不能,因为它返回每个级别的结果,但是数值解决方案是整个数据集的,而不是特定于级别的:
df %>% dplyr::group_by(LINE) %>% dplyr::summarise(get_prop(.))
编辑:请注意,我正在寻找的是一种在数据框中的因子水平上应用自定义函数的解决方案。如所示示例中,不一定是特定值的出现次数或比例。
编辑2:也就是说,我正在寻找一种利用上述get_prop
功能的解决方案。这不是因为它是解决此特定问题的最佳方法,而是因为它具有更广泛的通用性
如果要逐组应用自定义功能,则可以使用该group_split
命令。这会将您的数据框拆分为一个列表元素。每个列表元素都是df的子集。然后,您可以map
用来将函数应用于每个级别(请注意,您可以group_split
并且map
一步一步使用group_map
)。我添加了最后一行以获得原始方法的形式。
df %>%
group_by(LINE) %>%
group_split() %>%
map_dbl(get_prop) %>%
tibble(LINE = seq_along(.), CALL = .) # optional to get back to a df
#> # A tibble: 2 x 2
#> LINE CALL
#> <int> <dbl>
#> 1 1 0.833
#> 2 2 0.333
由reprex软件包(v0.3.0)创建于2020-01-20
现在,我担心此解决方案的一件事是group_split
删除分组变量(如果将其保留为列表或属性的名称,我会更喜欢)。因此,如果您希望小标题作为结果,则可以事先保存分组变量:
groups <- unique(df$LINE)
df %>%
group_by(LINE) %>%
group_split() %>%
map_dbl(get_prop) %>%
tibble(group = groups, result = .)
我认为总体上最干净的方法是这样(使用更一般的示例):
library(tidyverse)
df <- tibble(LINE=rep(c("a", "b"),each=6), FOUND=c(1,1,1,0,1,1,0,0,1,0,0,1))
lvls <- unique(df$LINE)
df %>%
group_by(LINE) %>%
group_map(~ get_prop(.x)) %>%
setNames(lvls) %>%
unlist() %>%
enframe()
#> # A tibble: 2 x 2
#> name value
#> <chr> <dbl>
#> 1 a 0.833
#> 2 b 0.333
由reprex软件包(v0.3.0)创建于2020-01-20
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句