【问题标题】:Subset dataframe in R, dplyr filter row values of column A not NA in row of column BR中的子集数据框,dplyr过滤列A的行值而不是B列的行中的NA
【发布时间】:2021-03-29 23:26:34
【问题描述】:

我有一个由时间序列研究组成的数据集。由于某些参与者在某些日子没有出现,因此他们对数据框的其余部分具有 NA 值,但某些研究日期至关重要,因此我试图将我的数据子集给参与者,以免错过这些关键日子。我的数据集实际上非常大,但总体结构如下:

fakedat <- data.frame(ID = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C", 
                          "D", "D", "D", "D", "E", "E", "E", "E", "F", "F", "F", "F"),
                           StudyDay = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 
                                        1, 2, 3, 4),
                           Ab = c(10, NA, 15, 10, 10, 20, 10, NA, 10, 10, NA, 30, NA, NA, 15, NA, 10, 20,
                                  10, 30, NA, 10, NA, 20))

现在假设它们在第 2 天和第 4 天出现至关重要,我尝试像这样使用 dplyr 过滤进行子集化:

fakedat2 <- fakedat %>%
  dplyr::group_by(ID) %>%
  dplyr::filter(StudyDay %in% c(2, 4) & !is.na(Ab)) %>%
  dplyr:: ungroup()

编辑:但是如果 ID 的 2 或 4 不是 NA 值,则此数据集的输出只是列表。我需要找到(在我的真实数据中)在 4 个特定研究日具有 NA Ab 值的受试者。 我在下面接受的答案有效,但仍然对执行条件过滤感到好奇?就像在 SAS 中一样,您可以编写“IF Ab!=NA at (StudyDay=2 AND St​​udyDay=4) THEN ID ....或类似的代码。

【问题讨论】:

    标签: r dataframe dplyr subset


    【解决方案1】:

    base R,我们可以做

    subset(fakedat, ID %in% ID[StudyDay %in% c(2, 4) & !is.na(Ab)])
    

    -输出

    #    ID StudyDay Ab
    #1   A        1 10
    #2   A        2 NA
    #3   A        3 15
    #4   A        4 10
    #5   B        1 10
    #6   B        2 20
    #7   B        3 10
    #8   B        4 NA
    #9   C        1 10
    #10  C        2 10
    #11  C        3 NA
    #12  C        4 30
    #17  E        1 10
    #18  E        2 20
    #19  E        3 10
    #20  E        4 30
    #21  F        1 NA
    #22  F        2 10
    #23  F        3 NA
    #24  F        4 20
    

    dplyr中的类似选项

    library(dplyr)
    fakedat %>%
         filter(ID %in% ID[StudyDay %in% c(2, 4) & !is.na(Ab)])
    

    【讨论】:

    • 感谢您的回答,我在最初的问题中犯了一个错误,我已修复 - 我没有意识到 [StudyDay %in% c(2, 4) &amp; !is.na(Ab)]) 正在返回主题,只要他们在两个 2 中都没有 NA和 4,至少在 1 中没有。他的解决方案,除了不必写出所有的日子(可能有几个)是制作所需的向量,两者都有效并且与您的结构相同。我是否可以检查这是一个解决方案,因为它只是针对我问错的问题?感谢您的帮助!
    【解决方案2】:

    也许这会实现您的目标。如果所有参与者都有所有StudyDay 时间点,并且您只想查看第 2 天或第 4 天是否没有丢失,您可以在您的filter 中检查这些时间点的Ab 值。在这种情况下,如果在第 2 天和第 4 天都是 NA(在本例中为“D”),则将省略 ID

    或者,如果您希望这两个值在第 2 天和第 4 天都可用,您可以使用 &amp; (AND) 而不是 | (OR)。

    library(dplyr)
    
    fakedat %>%
      group_by(ID) %>%
      filter(!is.na(Ab[StudyDay == 2]) | !is.na(Ab[StudyDay == 4]))
    

    如果您有多个天来检查是否没有丢失,您可以使用all 并检查NA 的值,其中StudyDay%in% 所需天数的向量,如下所示:

    required_vals <- c(2, 4)
    
    fakedat %>%
      group_by(ID) %>%
      filter(all(!is.na(Ab[StudyDay %in% required_vals])))
    

    输出

       ID    StudyDay    Ab
       <chr>    <dbl> <dbl>
     1 A            1    10
     2 A            2    NA
     3 A            3    15
     4 A            4    10
     5 B            1    10
     6 B            2    20
     7 B            3    10
     8 B            4    NA
     9 C            1    10
    10 C            2    10
    11 C            3    NA
    12 C            4    30
    13 E            1    10
    14 E            2    20
    15 E            3    10
    16 E            4    30
    17 F            1    NA
    18 F            2    10
    19 F            3    NA
    20 F            4    20
    

    【讨论】:

    • 您不仅是正确的,而且由于您的回答,我意识到我的代码是错误的。它为我提供了所有 ID 的数据框,其中 2 不是 NA 或 4 不是。你的答案给了我样本数据中需要的数据框,但不是我的实际数据——我仍然有一些带有 NA 值的关键日期。我改了“|”到 "&" `filter(!is.na(Ab[StudyDay == 2]) | !is.na(Ab[StudyDay == 4])' 这似乎是我现在需要的。
    • @jrokh 我想知道这个......我第一次发布答案时用 & (AND) 而不是 | (要么)。但我试图按预期匹配您的输出。它解决了问题 - 是否需要同时存在 2 和 4,或者只是两者之一。我们可以编辑答案或保持原样,并附上解释。
    • Gotcha-我编辑了我的问题,以便人们可以看到-我无法在任何地方找到一个好的答案)。是的,应该是 2 AND 4,所以我猜我的代码 2 OR 4 是否正确?我现在只有 4 个约会,但我可能会得到更多。有速记还是我必须写出 StudyDay== x?
    • @jrokh 查看已编辑的答案。您可以创建一个“所需天数”的向量,然后在您的filter 中使用all。这会检查 Ab 的值,以确保 NA 不包含在所需向量中的 StudyDay
    猜你喜欢
    • 2022-01-03
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多