将函数应用于r中的数据帧时未知的列

问题描述 投票:0回答:1

为了简化,比方说,我有一个这样的数据集:

num = c(1,2,3,"NA",3,4,1,2,1)
char = c('a','b','s','s','s','s','a','s','s')
t = as.data.frame(cbind(num,char))   

我写了一个函数来查找每列的前5个值:

 func_top5 = function(x){t%>%
    filter(!is.na(x))%>%
    group_by(x)%>%
    summarise(number_of_same_value = n())%>%
    arrange(desc(number_of_same_value))%>%
    slice(1:5)}

当我尝试将此功能应用于df时,

apply(t,2,func_top5)

它返回错误:

grouped_df_impl(data,unname(vars),drop)出错:列x未知

但是,当我单独使用该功能时,它完全正常:

t%>%
  filter(!is.na(num))%>%
  group_by(num)%>%
  summarise(number_of_same_value = n())%>%
  arrange(desc(number_of_same_value))%>%
  slice(1:5)

# A tibble: 5 x 2
     num number_of_same_value
  <fctr>                <int>
1      1                    3
2      2                    2
3      3                    2
4      4                    1
5     NA                    1

我认为问题可能是“group_by”函数。

谁能帮我这个?

r function dplyr
1个回答
0
投票

我们可以使用quosure方法来解决这个问题。假设他们输入参数'x'没有引用,我们可以用enquo将其转换为quosure,然后使用bang-bang运算符(group_by)在filter!!中进行评估。请注意,最好将数据集对象也作为函数可用性的输入参数以更一般的方式使用。目前尚不清楚是否引用了缺失值。如果它是真正的NA,更可接受的方式是is.na

func_top5 <- function(df, x){
   x <- enquo(x)
   df %>%
       filter(! (!!(x) %in% c("NA", "")))%>%
        group_by(!! x)%>%
        summarise(number_of_same_value = n())%>%
        arrange(desc(number_of_same_value))%>%
        slice(1:5)
     }

我们称之为

func_top5(df1, col1)
# A tibble: 2 x 2
#   col1  number_of_same_value
#   <chr>                <int>
#1 b                        3
#2 a                        2

在多列上执行此操作的一个选项是

map(names(t), ~ func_top5(t1, !! rlang::sym(.x)))
#[[1]]
# A tibble: 5 x 2
#    num number_of_same_value
#  <dbl>                <int>
#1  1.00                    3
#2  2.00                    2
#3  3.00                    2
#4  4.00                    1
#5 NA                       1

#[[2]]
# A tibble: 3 x 2
#  char  number_of_same_value
#  <chr>                <int>
#1 s                        6
#2 a                        2
#3 b                        1

data

df1 <- data.frame(col1 = c("a", "b", "NA", "", "a", "b", "b"), 
      col2 = rnorm(7), stringsAsFactors = FALSE)
© www.soinside.com 2019 - 2024. All rights reserved.