【问题标题】:Using filter in dplyr (version > 1.0.0) where both field and value are in variables在 dplyr(版本 > 1.0.0)中使用过滤器,其中字段和值都在变量中
【发布时间】:2021-05-05 20:34:24
【问题描述】:

我遇到了与问题Using filter_ in dplyr where both field and value are in variables 中描述的相同的问题。 但是,那里的答案已经过时了(基本 R 版本仍然有效,但我对 dplyr 版本感兴趣)。

search_col <- c("Species", "Sepal.Length")
search_value <- c("setosa", 5.0)

iris %>% filter_(.dots = paste0(search_col, "=='", search_value, "'"))

有人可以说明如何使用 dplyr 版本 > 1.0.0 重写它吗?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    1)首先要注意

    search_value <- c("setosa", 5.0)
    

    将强制 5.0 转换为字符,所以这是有问题的。而是创建一个数据框,然后使用inner_join

    (如果 search_value 都是字符串而不是字符串和数字的混合,那么就问题中显示的变量而言,我们可以使用注释掉的行,或者我们可以使用 search_cols 代替下面的名称(searchDF)和在其他地方使用 search_value 代替 searchDF。)

    # searchDF <- as.data.frame(setNames(as.list(search_value), search_col))
    searchDF <- data.frame(Species = "setosa", Sepal.Length = 5.0)
    inner_join(iris, searchDF, by = names(searchDF))
    

    给予:

      Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    1            5         3.6          1.4         0.2  setosa
    2            5         3.4          1.5         0.2  setosa
    3            5         3.0          1.6         0.2  setosa
    4            5         3.4          1.6         0.4  setosa
    5            5         3.2          1.2         0.2  setosa
    6            5         3.5          1.3         0.3  setosa
    7            5         3.5          1.6         0.6  setosa
    8            5         3.3          1.4         0.2  setosa
    

    2) 如果必须使用filter,则使用cur_data() 引用数据。标量变量可以直接使用。

    filter(iris, cur_data()[, names(searchDF)[1]] == searchDF[[1]] &
      cur_data()[, names(searchDF)[2]] == searchDF[[2]])
    

    3) 对于任意数量的条件,请使用 reduce(来自 purrr)或 Reduce(来自基础 R)。

    library(dplyr)
    library(purrr)
    
    myfilter <- function(x, nm) filter(x, cur_data()[, nm] == searchDF[[nm]])
    iris %>% reduce(names(searchDF), myfilter, .init = .)
    

    【讨论】:

    • 浮点相等的假设存在风险(stackoverflow.com/q/9508518stackoverflow.com/q/588004en.wikipedia.org/wiki/IEEE_754)。虽然它在这里似乎工作得很好,但不难想出它不会按预期工作的例子。 (最大的问题是它不会告诉你有问题,它只会返回比预期更少的记录。)作为替代方案,我建议使用sqldfdata.table 进行基于范围的连接。
    • ... 或 fuzzyjoin.
    • @r2evans,虽然这是一个附带问题,与问题的主要意图并不完全相关。
    • 我并不是说关于 SO 的每个答案都必须考虑所有可能性,但 this 肯定属于我所谓的常见误解一般来说,编程和数据科学的东西。无论哪种方式,我的评论的重点不是要从您的解决方案中删除,而是要确定浮点相等性测试存在经常被掩盖的风险。
    • 谢谢,inner_join 也是一个很好的解决方案,就像 base R 一样,可能还有许多其他方法。我对带有过滤器的解决方案特别感兴趣,其方式与示例代码中的类似。关于强制,很好,但这里的重点不是那个,在我的真实数据中我只有字符串。您的过滤器解决方案有效,但如果我有超过 2 个键值对,它就不能很好地概括。我对如何重写我在问题中提出的那段代码真的很感兴趣。
    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 2022-01-18
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多