【问题标题】:How to create multiple filters within same function in R?如何在 R 中的同一函数中创建多个过滤器?
【发布时间】:2017-12-12 17:15:24
【问题描述】:

我已经编写了一些代码来帮助解决之前回答的问题。最初我有这个代码:

getT <- function(df, ID, Number){
  df %>%
    group_by(ID, Number) %>% 
    mutate( Distance = finish - begin) %>% 
    select(-begin,-finish,-symbols) %>%
    nest() %>% 
    mutate( data = map( data, ~ filter(.x, Distance == max(Distance)))) %>% 
    unnest()
}

getallT <- as.data.frame(getT(df))

getTID <- function(df, ID) {
  subset(x = getallT, subset = (ID))
}

它给出了这个输出:

ID     Number     Time     Distance
33         1      2.00         870
33         2      1.98         859
33         3      0.82         305
33         4      2.02         651
33         5      2.53         502

我想通过Time 过滤它,所以我使用了这个代码(感谢下面的帖子):

getHLN <- function(df, ID) {
  getallT %>% filter (ID ==id & !between(Time, 1.50, 2.10))
}

现在给出这个输出:

  ID Number Time Distance
1 33      3 0.82      305
2 33      4 2.02      651
3 33      5 2.53      502

但是现在我遇到了一个问题,所以现在我想知道如何: A. 过滤掉数字 4 和 5,以便我可以使用不同的 Time 过滤器创建一个单独的函数。稍后创建另一个不同的函数,将之前的两个函数合并为一个。 要么 B. 为同一函数中的数字 4 和 5 创建一个不同的 Time 过滤器。

我尝试通过使用 filter (getallT, Number &gt;= 3) %&gt;% 来做 A. 但不起作用。如果可能的话,我宁愿和B一起去。所以像... 对于 ID 号 1-3:filter(!between(Time,1,2)) 对于 ID 号 4-5: filter(!between(Time 1.5,2.3)) 在同一函数中。 过去一天我一直在尝试一些事情,但不断收到错误消息,例如 Error in filter_impl(.data, quo) : Evaluation error: operations are possible only for numeric, logical or complex types.

我一直在尝试这里的内容,但一定不能写东西,所以需要一些见解! http://genomicsclass.github.io/book/pages/dplyr_tutorial.html

这是一个示例数据集

df <- data.frame(ID=rep(33,5),
                 Number=1:5,
                 Time=c(2.00,1.98,0.82,2.02,2.53),
                 Distance=c(870,859,305,651,502))

任何帮助将不胜感激。

【问题讨论】:

  • 你能提供一个可重现的小例子
  • 请养成这样的习惯,因为您提出包含可重现数据集的问题。 stackoverflow.com/questions/5963269/…
  • 我确实有忘记添加的坏习惯!糟糕,谢谢提醒!

标签: r function dataframe filter dplyr


【解决方案1】:

这个函数有点混乱:

getHLN <- function(df, ID) {
  data_df1 <- getT(race_df)
  subset(x = getallT, subset = (ID)) %>%
    filter (!between(Time, 1.50, 2.10))
}

主要是因为它接受了一个不在其中的df 参数,并在race_dfgetallT 中使用了来自外部环境的两个data.frame。你对subset 的电话也有点神秘。就目前而言,该函数将返回以subset 开头的表达式将返回的任何内容,并将丢弃data_df1

getHLN <- function(df, ID) {
  # this gets locally assigned within the function and then 
  # becomes unreachable once the function ends
  data_df1 <- getT(df)
  # this expression would produce the last value of the function
  # and so the function would return its value
  subset(x = getallT, subset = (ID)) %>%
    filter (!between(Time, 1.50, 2.10))
}

我们可以通过为您描述的两组标准创建ID %in% ... &amp; !between() 逻辑来执行您描述的那种过滤,将每个标准包装在括号中以便它们被评估为“和”逻辑,然后将两者都添加到@987654330 @ 函数并将它们与| 运算符(“或”)连接起来,filter 将评估为“filter df where (criteria a AND B) OR (criteria c AND d)”。

getHLN <- function(df) {
  df %>% filter(
    (Number %in% 1:3 & !between(Time, 1, 2)) |
      (Number %in% 4:5 & !between(Time, 1.50, 2.10))
    )
}

【讨论】:

  • 在进一步摆弄时,我意识到我的 data_df1 毫无意义,但现在你向我展示了一个更时尚的代码,因此我感谢你。我在 R 语言中自学成才,对编程也很陌生。我相信你能说出来。有没有办法可以为Number 4 和 5 添加另一个与Time 相关的filter?我不断收到相同的错误消息。
  • 啊,是的,我重新阅读了你的问题,现在看看你希望做什么——请看我修改后的答案。
  • 感谢您的帮助!我的代码看起来更好,现在可以运行了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多