【问题标题】:Check if value of column A is present in the same row or previous rows of column B检查A列的值是否存在于B列的同一行或前几行中
【发布时间】:2021-10-26 19:36:37
【问题描述】:

我有这个数据框:

df <- structure(list(A = 1:5, B = c(1L, 5L, 2L, 3L, 3L)), 
                class = "data.frame", row.names = c(NA, -5L))

  A B
1 1 1
2 2 5
3 3 2
4 4 3
5 5 3

我想得到这个结果:

  A B Result
1 1 1      B
2 2 5   <NA>
3 3 2   <NA>
4 4 3   <NA>
5 5 3      B

策略:

  1. 检查是否A==B 然后将B 分配给新列Result 如果不是NA
  2. 但也对B 的所有PREVIOUS 行执行此操作。

目标:

我想学习如何检查列 A 的某个值是否在第 5 行中 位于B 列的前几行(例如,第 1-4 行)。

【问题讨论】:

    标签: r dataframe dplyr match tidyverse


    【解决方案1】:

    我们可以使用

    library(dplyr)
    library(purrr)
    df %>% 
       mutate(Result = map_chr(row_number(), ~ case_when(A[.x] %in% B[seq(.x)]~ "B")))
    

    -输出

     A B Result
    1 1 1      B
    2 2 5   <NA>
    3 3 2   <NA>
    4 4 3   <NA>
    5 5 3      B
    

    【讨论】:

      【解决方案2】:

      只是对@ThomasIsCoding 的答案进行了一些小改动以使其成为 dplyr。在我看来,布局稍微更容易阅读。

      library(tidyverse)
      df <- structure(list(A = 1:5, B = c(1L, 5L, 2L, 3L, 3L)), 
                      class = "data.frame", row.names = c(NA, -5L))
      match(df$A, df$B)
      #> [1]  1  3  4 NA  2
      df %>% mutate(Result = if_else(match(A, B) <= row_number(), 
                                     "B", 
                                     NA_character_))
      #>   A B Result
      #> 1 1 1      B
      #> 2 2 5   <NA>
      #> 3 3 2   <NA>
      #> 4 4 3   <NA>
      #> 5 5 3      B
      

      由 reprex 包 (v1.0.0) 于 2021-08-26 创建

      【讨论】:

      • 这看起来很好。我将在我的用例上进行尝试。在我的案例中,类似的方法失败了。但我现在会看到。
      • 谢谢,这很有帮助。
      【解决方案3】:

      这是dplyr::rowwise 方法:

      library(dplyr)
      
      df %>%
        rowwise %>% 
        mutate(result = ifelse(A %in% .[seq(cur_group_rows()),]$B, "B", NA))
      
      #> # A tibble: 5 x 3
      #> # Rowwise: 
      #>       A     B result
      #>   <int> <int> <chr> 
      #> 1     1     1 B     
      #> 2     2     5 <NA>  
      #> 3     3     2 <NA>  
      #> 4     4     3 <NA>  
      #> 5     5     3 B
      

      reprex package (v0.3.0) 于 2021 年 8 月 26 日创建

      【讨论】:

      • 谢谢 TimTeaFan。这个也很不错!
      • 也许你应该考虑在你的包中实现这个过程的动词?
      【解决方案4】:

      我希望以下代码适合您的一般情况

      transform(
        df,
        Result = replace(rep(NA, length(B)), match(A, B) <= seq_along(A), "B")
      )
      

      给了

        A B Result
      1 1 1      B
      2 2 5   <NA>
      3 3 2   <NA>
      4 4 3   <NA>
      5 5 3      B
      

      【讨论】:

      • 此解决方案是否假设 A 始终为 1,2,3 ...?
      • @ArthurYip 不,它可以是任何数字向量。
      • 哦,我明白了,如果匹配在一行中
      • @ThomasIsCoding。非常感谢。在您的帮助下,我能够解决此任务 stackoverflow.com/questions/68940682/…>
      • 这个可以打到"B"[NA^(!match(df$A, df$B) &lt;= seq_along(df$A))]吗?
      猜你喜欢
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2020-05-06
      • 2022-08-26
      • 1970-01-01
      相关资源
      最近更新 更多