如何根据另一个因素构建自定义函数以获取一个因子的频率?

时间:2017-09-01 18:34:42

标签: r frequency tidyverse custom-function

我有一个包含大量因素的数据集,我想根据另一个因素得出每个因子的相对频率。例如,让我们使用mtcars:

mtcars$am <- as.factor(mtcars$am)
mtcars$cyl <- as.factor(mtcars$cyl)

我希望根据cyl的值得到am == 1的频率。在这种情况下,我应该得到三个相对频率,因为cyl有三个级别(4,6和8)。我有这个代码工作:

mtcars %>%
  select(am, cyl) %>%
  table(.) %>% 
  prop.table(., 1) %>% 
  round(., digits = 2) %>% 
  data.frame() %>% 
  filter(am == 1) %>% 
  t() %>% 
  data.frame() %>% 
  slice(3)

# # A tibble: 1 x 3
#       X1     X2     X3
#   <fctr> <fctr> <fctr>
# 1   0.62   0.23   0.15

如果你运行它,你将获得上面的三个频率。当然,我构建了这个代码,所以我知道X1对应于cyl == 4,X2是cyl == 6,X3是cyl == 8的频率。

现在,我想用大量因素(像am这样的其他二元因子)来做这件事。所以,我想构建一个自定义函数,稍后将所有频率绑定为行,并创建一个包含这些频率的漂亮表。现在,我有这个:

pull_freq <- function(mydata, var1, var2){      
 require(tidyverse)   
  var1 <- enquo(var1)
  var2 <- enquo(var2)
  mydata %>%
    select(!!var1, !!var2) %>%
    table(.) %>% 
    prop.table(., 1) %>% 
    round(., digits = 2) %>% 
    data.frame() %>% 
    filter(!!var1 == 1) %>% 
    t() %>% 
    data.frame() %>% 
    slice(3)
}

pull_freq(mtcars, am, cyl)

# A tibble: 1 x 0

但正如您所看到的,当我运行此功能时,我没有得到任何输出。为什么我没有得到任何输出的任何想法?我怎样才能使这个功能起作用?谢谢!

3 个答案:

答案 0 :(得分:1)

自定义功能

myfun <- function(df, col1, col2, col3) {
            require(dplyr)
            require(tidyr)
            col1 <- enquo(col1)
            col2 <- enquo(col2)
            df %>% 
              count(!!col1, !!col2) %>% 
              group_by(!!col1) %>%
              mutate(tot = sum(n)) %>%
              ungroup() %>%
              group_by(!!col2) %>% 
              mutate(n = n / tot) %>%
              select(-tot) %>% 
              filter(UQ(col1)==1) %>%
              spread_(col3, "n") %>%
              round(., digits=2)
        }

输出

myfun(mtcars, am, cyl, "cyl")

# am    `4`   `6`   `8`
#  1  0.62  0.23  0.15

答案 1 :(得分:0)

也许我完全不在了,但就是这样吗?

data(mtcars)

agg <- aggregate(mtcars$cyl, list(mtcars$cyl, mtcars$am), FUN = length)
names(agg) <- c("cyl", "am", "count")

agg$freq <- ave(agg$count, agg$am, FUN = function(x) x/sum(x))
agg <- t(agg[-3])
agg

请注意,我没有将cylam强制转换为as.factor的因素。这是因为当数据帧被转置时,结果将是matrix。由于矩阵只能包含一个类的元素,因此所有值都将变为类characterfreq值不再是数字。

答案 2 :(得分:0)

这个怎么样,

library(tidyverse)
getFreq <- function(data, group_var, value_var) {
    data %>%
        group_by_(group_var) %>%
        do({
            table(.[[value_var]]) %>%
                prop.table() %>%
                as_tibble()
        }) %>%
        spread(Var1, n)
}

getFreq(mtcars, "am", "cyl") %>% print()

您可以在之后进行所有过滤,或者只是包含在函数内部。