【问题标题】:Issue with filtering within a function in RR中函数内过滤的问题
【发布时间】:2020-02-01 14:39:26
【问题描述】:

我希望有人可以帮助我解决我在创建函数时遇到的问题。我使用的数据集包含调查回复,每个问题(Q1、Q2 等)都有一列,每一行都有回复。该函数必须能够选择列(Q1、Q2 等),然后从该列中过滤一个特定的响应,以便对其进行计数。

我正在尝试编写一个函数,该函数允许您包含要选择的问题编号作为参数之一。这是代码:

my_function <- function(survey, question_number) {
  selected_question <- survey %>%
    select(question_number)
  everyday_responses <- selected_question %>%
    filter(question_number == "Every day") %>%
    count()

这适用于选择列,但不适用于在该列中进行过滤。我发现这是因为我必须将 question_number 参数输入为“Q1”(用引号括起来)。这导致 filter(question_number == "Every day") 行无法正常工作,因为这需要没有“”的列名(Q1 不是“Q1”)。

谁能解释为什么会发生这种情况并可能提出修复建议?我对使用 R 很陌生,所以我可能完全错过了一些东西。

在此先感谢 :D

【问题讨论】:

标签: r function filter dplyr


【解决方案1】:

一般selectpull 可以使用原始列名 (Q1) 和字符串列名 ("Q1"),但 filtermutate、... 需要原始列名。

假设您真的只对问题中“每天”的数量感兴趣,您可以使用 base R:

my_function_base <- function(survey, question_number) {

  sum(survey[[question_number]] %in% "Every day")

}

my_function_base(my_df, "Q2")
# [1] 1

修复您的 dplyr 函数有多种可能性,但这里有两种选择。

library(dplyr)

使用字符串输入

my_function_str <- function(survey, question_number) {

  survey %>%
    filter_at(question_number, ~ . == "Every day") %>%
    count()
}

my_function_str(my_df, "Q2")
# A tibble: 1 x 1
#       n
#   <int>
# 1     1

filter_at 使用字符串作为输入,然后在指定的列进行过滤。

使用 NSE: 参见:https://dplyr.tidyverse.org/articles/programming.html

my_function_nse <- function(survey, question_number) {
  question_number <- enquo(question_number)

  survey %>%
    filter(!!question_number == "Every day") %>%
    count()
}

my_function_nse(my_df, Q1) # No quotes around Q1

# A tibble: 1 x 1
#       n
#   <int>
# 1     2

数据

my_df <- data.frame(Q1 = c("Every week", "Every day", "Every week", "Every day"), 
                    Q2 = c("Every week", "Every week", "Every week", "Every day"))

【讨论】:

  • 非常感谢您这么快回复我!当我运行第一个选项(即使使用您的数据)时,我收到错误消息“错误:.vars_predicate 必须是对all_vars()any_vars() 的调用,而不是公式”。我认为这与 filter_at() 的语法有关,但无法弄清楚为什么会发生这种情况。知道为什么这对我不起作用吗?
  • 嗯,你的例子是我的错误还是你的?您正在开发哪个版本?您应该可以通过指定 filter_at(question_number, all_vars(. == "Every day")) 来解决此问题
  • 行得通!再次感谢您的帮助:)
【解决方案2】:

@zx8754 分享的链接应该可以帮助您解决您遇到的问题。考虑到您说您是R 的新手,您可以在这里修改您的功能。

my_function <- function(df, col) {
  df %>%
    select(col) %>%
    filter((!!as.symbol(col))=="Every day") %>%
    count()
}
# This is how you call your function
my_function(df, "Q1")

df 您的数据框在哪里,我认为它被称为surveycol 是您要过滤到的列。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 2019-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-03-25
    • 1970-01-01
    相关资源
    最近更新 更多