R 在数据帧中的因子级别上应用自定义函数

R 在数据帧中的因子级别上应用自定义函数,r,R,我正在尝试应用一种基于tidyverse的方法,或者至少是一种整洁的解决方案,用于在数据帧中的因子级别上应用自定义函数 考虑以下测试数据集: 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

我正在尝试应用一种基于tidyverse的方法,或者至少是一种整洁的解决方案,用于在数据帧中的因子级别上应用自定义函数

考虑以下测试数据集:

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
编辑:请注意,我正在寻找的是一种解决方案,用于在数据帧中的因子级别上应用自定义函数。它不一定是特定值出现的次数或比例,如示例所示


编辑2:也就是说,我正在寻找一种利用上面的
get_prop
功能的解决方案。这并不是因为它是解决此特定问题的最佳方法,而是因为它更具通用性

如果要按组应用自定义函数,可以使用
group\u split
命令。这将把数据框拆分为列表的元素。每个列表元素都是df的子集。然后,您可以使用
map
将功能应用到每个级别(请注意,您可以使用
group\u map
一步完成
group\u split
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
更新 我认为总体上最干净的方法是这样的(使用一个更一般的例子):

库(tidyverse)
df%
组映射(~get_prop(.x))%>%
设置名称(LVL)%>%
取消列表()%>%
enframe()
#>#tibble:2x2
#>名称值
#>    
#>1 a 0.833
#>2 b 0.333

由(v0.3.0)于2020-01-20创建如果您想在组方面应用自定义函数,可以使用
group\u split
命令。这将把数据框拆分为列表的元素。每个列表元素都是df的子集。然后,您可以使用
map
将功能应用到每个级别(请注意,您可以使用
group\u map
一步完成
group\u split
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
更新 我认为总体上最干净的方法是这样的(使用一个更一般的例子):

库(tidyverse)
df%
组映射(~get_prop(.x))%>%
设置名称(LVL)%>%
取消列表()%>%
enframe()
#>#tibble:2x2
#>名称值
#>    
#>1 a 0.833
#>2 b 0.333

由(v0.3.0)于2020年1月20日创建的另一个选项是使用
group\u map
,然后使用
tibble::enframe

library(dplyr)

df %>% 
group_by(LINE) %>% 
group_map(~get_prop(.)) %>% 
unlist() %>% 
tibble::enframe()

#  name value
#  <int> <dbl>
#1     1 0.833
#2     2 0.333

另一种选择是使用
group\u map
,然后使用
tibble::enframe

library(dplyr)

df %>% 
group_by(LINE) %>% 
group_map(~get_prop(.)) %>% 
unlist() %>% 
tibble::enframe()

#  name value
#  <int> <dbl>
#1     1 0.833
#2     2 0.333

请注意,我已经编辑了这个问题,所以我要找的是一种按因子级别调用通用或自定义函数的方法,而不必计算比例。啊,我明白了。我以为你只是想得到这个函数的结果。它必须是问题中的确切的
get_prop
函数吗?最好是这样。这样,该解决方案将更容易推广到任何自定义函数,并有另一种外观。我想这应该是你想要的。我正要问关于分组变量名的问题!谢谢你的编辑请注意,我已经编辑了这个问题,所以我要找的是一种按因子级别调用通用或自定义函数的方法,而不必计算比例。啊,我明白了。我以为你只是想得到这个函数的结果。它必须是问题中的确切的
get_prop
函数吗?最好是这样。这样,该解决方案将更容易推广到任何自定义函数,并有另一种外观。我想这应该是你想要的。我正要问关于分组变量名的问题!谢谢你的编辑
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
library(dplyr)

df %>% 
group_by(LINE) %>% 
group_map(~get_prop(.)) %>% 
unlist() %>% 
tibble::enframe()

#  name value
#  <int> <dbl>
#1     1 0.833
#2     2 0.333
df %>%
    group_by(LINE) %>%
    group_modify(~ tibble::enframe(get_prop(.), name = NULL))

# LINE  value
#  <chr> <dbl>
#1 a     0.833
#2 b     0.333