在 R 中,如何根据另一个单元格的值删除一系列单元格?

In R, how to delete a series of cells based on the value from another cell?

我有一个 300x300 的 df。每行代表不同患者的数据,以 id 命名。前两列是患者 ID。列 'id_all' 包含的参与者多于需要,多于 'id'。我的目标是仅保留与第一列 'id'.

相对应的患者信息

第一个 9x9 看起来像这样:

id id_all MMSE BL MMSE 12 MMSE 24 MMSE 36 MMSE 48 MMSE 60 MMSE 72
aaa002 aaa000 22 18 NA NA NA NA NA
aaa003 aaa002 29 28 28 29 30 29 NA
aaa005 aaa003 30 29 30 30 30 NA NA
aaa024 aaa005 29 28 25 NA NA 25 NA
aaa026 aaa024 30 29 29 29 NA NA NA
aaa048 aaa026 28 30 28 27 30 30 NA
aaa095 aaa038 29 29 29 26 NA NA NA
aaa222 aaa048 30 29 29 28 28 29 NA

因此,基于第一列,我想以某种方式遍历第二列,并删除与第一列不匹配的参与者的所有信息,'id'. 这意味着,在第一行中,删除列 2:300,并保持第一列不变。

最后,我希望我的 df 看起来像这样:

id id_all MMSE BL MMSE 12 MMSE 24 MMSE 36 MMSE 48 MMSE 60 MMSE 72
aaa002 aaa002 29 28 28 29 30 29 NA
aaa003 aaa003 30 29 30 30 30 NA NA
aaa005 aaa005 29 28 25 NA NA 25 NA
aaa024 aaa024 30 29 29 29 NA NA NA
aaa026 aaa026 28 30 28 27 30 30 NA
aaa048 aaa048 30 29 29 28 28 29 NA
aaa095 ...
aaa222 ...

在此示例中,id_all aaa000 和 aaa038 在 id 列中没有匹配项,因此我想删除有关这些参与者的所有信息。 我不知道如何删除几乎所有行(几乎是因为只剩下前两个单元格),以及如何将所有单元格向上移动。

另一种可能性是,将第一列向下移动直到 id 匹配 id_all,然后删除 id 列中有空单元格的整行.

谢谢!

在 tidyverse 中:

library(dplyr)
df %>% 
  filter(id == id_all)

基地内:

df[df$id == df$id_all, ]

我认为这会达到目的

library(tidyverse)

df %>% filter(!is.na(match(id_all, df$id))) %>% select(-id)

  id_all MMSE.BL MMSE.12 MMSE.24 MMSE.36 MMSE.48 MMSE.60 MMSE.72
1 aaa002      29      28      28      29      30      29      NA
2 aaa003      30      29      30      30      30      NA      NA
3 aaa005      29      28      25      NA      NA      25      NA
4 aaa024      30      29      29      29      NA      NA      NA
5 aaa026      28      30      28      27      30      30      NA
6 aaa048      30      29      29      28      28      29      NA

由于id == id_all在最终数据中,不需要重复的列。如果需要,可以通过在上述语法

末尾添加mutate(id = id_all)来轻松创建
df %>% filter(!is.na(match(id_all, df$id))) %>% select(-id) %>% mutate(id = id_all) %>%
  select(id, everything())

      id id_all MMSE.BL MMSE.12 MMSE.24 MMSE.36 MMSE.48 MMSE.60 MMSE.72
1 aaa002 aaa002      29      28      28      29      30      29      NA
2 aaa003 aaa003      30      29      30      30      30      NA      NA
3 aaa005 aaa005      29      28      25      NA      NA      25      NA
4 aaa024 aaa024      30      29      29      29      NA      NA      NA
5 aaa026 aaa026      28      30      28      27      30      30      NA
6 aaa048 aaa048      30      29      29      28      28      29      NA
使用了

dputdf

df <- structure(list(id = c("aaa002", "aaa003", "aaa005", "aaa024", 
"aaa026", "aaa048", "aaa095", "aaa222"), id_all = c("aaa000", 
"aaa002", "aaa003", "aaa005", "aaa024", "aaa026", "aaa038", "aaa048"
), MMSE.BL = c(22L, 29L, 30L, 29L, 30L, 28L, 29L, 30L), MMSE.12 = c(18L, 
28L, 29L, 28L, 29L, 30L, 29L, 29L), MMSE.24 = c(NA, 28L, 30L, 
25L, 29L, 28L, 29L, 29L), MMSE.36 = c(NA, 29L, 30L, NA, 29L, 
27L, 26L, 28L), MMSE.48 = c(NA, 30L, 30L, NA, NA, 30L, NA, 28L
), MMSE.60 = c(NA, 29L, NA, 25L, NA, 30L, NA, 29L), MMSE.72 = c(NA, 
NA, NA, NA, NA, NA, NA, NA)), class = "data.frame", row.names = c(NA, 
-8L))

> df
      id id_all MMSE.BL MMSE.12 MMSE.24 MMSE.36 MMSE.48 MMSE.60 MMSE.72
1 aaa002 aaa000      22      18      NA      NA      NA      NA      NA
2 aaa003 aaa002      29      28      28      29      30      29      NA
3 aaa005 aaa003      30      29      30      30      30      NA      NA
4 aaa024 aaa005      29      28      25      NA      NA      25      NA
5 aaa026 aaa024      30      29      29      29      NA      NA      NA
6 aaa048 aaa026      28      30      28      27      30      30      NA
7 aaa095 aaa038      29      29      29      26      NA      NA      NA
8 aaa222 aaa048      30      29      29      28      28      29      NA