【问题标题】:R Subsetting IDs that contain multiple keywordsR子集包含多个关键字的ID
【发布时间】:2021-09-18 05:08:04
【问题描述】:

我需要根据 ID 是否包含一对关键字来对我的数据框进行子集化。我的数据是这样的:

Keyword  | ID
CVa      | 1
CVa      | 2
CVa      | 6
TST      | 3 
TST      | 3 
TST      | 2 
TST      | 2 
TST      | 4 
TST      | 5 
QFT      | 1
QFT      | 3 
QFT      | 6

我需要对所有具有 CVa 和 TST 或 CVa 和 QFT 关键字配对的行进行子集化。因此,例如,我想要 ID 为 1、2 和 6 的所有行。

这就是我现在所拥有的,但它并没有按照我需要的方式组合关键字。

CVaSubset <- subset(CleanKeys, subset = (CleanKeys$keyword == 'CVa' | CleanKeys$keyword == 'TST' | Cleankeys$keyword == 'QFT') 

这是子集,但我没有得到我需要的组合。我也试过了:

CVaSubset <- subset(CleanKeys, subset = ( (CleanKeys$keyword == 'CVa' & CleanKeys$keyword == 'TST') |(CleanKeys$keyword == 'CVa' & Cleankeys$keyword == 'QFT') 

我想我缺少 group_by 语句,但我不知道如何获得这两个关键字的组合。

编辑:

我在包含许多其他关键字的综合数据集上处理此代码并收到错误:

"Error: Can't subset columns that don't exist. x Columns CFC, CFC, CFC, CFC, CFC, etc. don't exist."

我解决了这个问题,但现在我在过滤步骤后收到错误:

x operations are possible only for numeric, logical or complex types

但是,我的一些关键字是连字符的,所以我认为这是问题所在。我把名字放在``里,我希望这能解决问题。

【问题讨论】:

    标签: r dplyr subset


    【解决方案1】:

    如果满足以下条件,则根据您的规范过滤数据会更容易 您的数据以“整洁”的方式组织。这意味着每个案例,代表 通过唯一的ID 值,在一行中。

    我们可以通过tidyr::pivor_wider() 实现这一目标。 pivot_wider() 需要一个列来为宽格式绘制变量名,并且 要从中提取值的另一列。您的数据只有名称列 (Keyword)。 使用dplyr::mutate(),我们为每一行创建一个为TRUE 的虚拟变量。通过指定 pivot_wider()values_fill 参数为 FALSE,每个单元格 表示关键字不存在的情况,将填充 FALSE.

    library(tidyverse)
    tidy_data <-
      data %>%
      unique() %>%
      mutate(dummy = TRUE) %>%
      pivot_wider(
        id_cols = ID,
        names_from = Keyword,
        values_from = dummy,
        values_fill = FALSE
      )
    
    tidy_data
    #> # A tibble: 6 x 4
    #>      ID CVa   TST   QFT  
    #>   <int> <lgl> <lgl> <lgl>
    #> 1     1 TRUE  FALSE TRUE 
    #> 2     2 TRUE  TRUE  FALSE
    #> 3     6 TRUE  FALSE TRUE 
    #> 4     3 FALSE TRUE  TRUE 
    #> 5     4 FALSE TRUE  FALSE
    #> 6     5 FALSE TRUE  FALSE
    

    现在我们可以按照您描述的方式轻松过滤数据。

    dplyr::filter():

    tidy_data %>%
      filter((CVa & TST) | (CVa & QFT))
    #> # A tibble: 3 x 4
    #>      ID CVa   TST   QFT  
    #>   <int> <lgl> <lgl> <lgl>
    #> 1     1 TRUE  FALSE TRUE 
    #> 2     2 TRUE  TRUE  FALSE
    #> 3     6 TRUE  FALSE TRUE
    

    base::subset()

    subset(tidy_data, (CVa & TST) | (CVa & QFT))
    #> # A tibble: 3 x 4
    #>      ID CVa   TST   QFT  
    #>   <int> <lgl> <lgl> <lgl>
    #> 1     1 TRUE  FALSE TRUE 
    #> 2     2 TRUE  TRUE  FALSE
    #> 3     6 TRUE  FALSE TRUE
    

    【讨论】:

    • 这太棒了!非常感谢,但我收到与我不关心的一些关键字有关的错误:错误:无法对不存在的列进行子集化。 x 列CFCCFCCFCCFCCFC 等不存在。
    • 当您对问题中使用的数据执行代码或将其应用于另一个/完整数据集时,您是否会收到该错误?在哪个命令之后您会收到该错误?请编辑您的原始问题以反映此问题。
    • 我更新了它,我认为问题可能源于关键字名称被连字符。
    • 您能否在您的问题中包含一个导致该问题的数据示例?另外请添加您尝试过的代码。还请分享您为解决第一个问题所做的代码。
    【解决方案2】:

    如果我理解正确,OP 想要识别 Cleankeys 中包含 both 关键字 CVaTSTboth 关键字的所有 ID CVaQFT。然后,OP 想要使用已识别的 IDs 对 Cleankeys 进行子集化。

    可以在数据文件中定义所需的关键字对,而不是硬编码条件:

    # Required keyword pairings
    pairs <- readr::read_table("
    Keyword1 Keyword2
    CVa      TST
    CVa      QFT")
    

    请注意,关键字对必须按行排序,即每一行都满足条件Keyword1 &lt; Keyword2。该数据文件可以任意扩展,以根据需要包含尽可能多的关键字对。

    现在,我们可以为CleanKeys 中的每个ID 创建所有可能的关键字对组合,并将其与所需的关键字配对进行比较。然后,那些具有出现在所需关键字配对中的关键字对的 ID 用于子集CleanKeys

    library(dplyr)
    CleanKeys %>% 
      inner_join(x = ., y = ., by = "ID", suffix = c("1", "2")) %>% 
      filter(Keyword1 < Keyword2) %>% 
      right_join(pairs) %>% 
      select(ID) %>% 
      arrange() %>% 
      unique() %>% 
      left_join(CleanKeys)
    
         ID Keyword
      <dbl> <chr>  
    1     1 CVa    
    2     1 TST    
    3     1 QFT    
    4     2 CVa    
    5     2 TST    
    6     6 CVa    
    7     6 QFT
    

    数据

    CleanKeys <- readr::read_delim("
    Keyword  | ID
    CVa      | 1
    CVa      | 2
    CVa      | 6
    TST      | 3 
    TST      | 3 
    TST      | 1 
    TST      | 2 
    TST      | 4 
    TST      | 5 
    QFT      | 1
    QFT      | 3 
    QFT      | 6", 
    delim = "|", trim_ws = TRUE)
    

    【讨论】:

    • 没错,我正在尝试返回重叠的值。硬编码值是否存在固有问题?除了每次更改子集参数时都需要更改吗?
    • @MeredithAbrams 不,硬编码没有固有的问题。另一方面,我了解到让事情变得灵活和可配置可能是值得的。它是关于将规则和结构(例如程序代码)与易失性数据分开。
    猜你喜欢
    • 2018-03-13
    • 2021-07-20
    • 2017-03-15
    • 2019-09-26
    • 2014-01-24
    • 1970-01-01
    • 2016-05-20
    • 2022-11-28
    • 1970-01-01
    相关资源
    最近更新 更多