检查列表中的所有多个值是否都存在于数据帧中

Check if all multiple values in a list exist in a dataframe

提问人:Michael Schulte 提问时间:11/30/2022 最后编辑:zx8754Michael Schulte 更新时间:5/15/2023 访问量:251

问:

我有一个数据帧 df,它包含 ids = (1, 2, 3, 4),我有一个列表 items,其中包含 (“a”, “b”, “c”)。我想返回包含“a”、“b”和“c”的 id。除非 id 至少包含列表中的所有 3 个项目,否则它不应返回。这应该是可扩展的,以涵盖列表中有 n 个项目的情况。

    df <- data.frame(ID = (1, 2, 2, 3, 3, 3, 4, 4, 4, 4), 
                     values = ("b", "a", "c", "a", "b", "c", "a", "b", "c", "d"))
    items <- list("a", "b", "c")

DF 如下所示:

编号
1 b
2 一个
2 c
3 一个
3 b
3 c
4 一个
4 b
4 c
4 d

该函数应返回 ID = (3, 4),但对于 ID = 4,只有值 = (“a”, “b”, “c”) 应返回。它不应返回 ID = (1, 2)。 这是我尝试过的,但它没有返回我想要的。它当前返回的是一个数据帧,里面没有任何内容。每一列都为 NULL。

Criteria.Match <- function(df, CriteriaList, criteria.string){
Pat <- as.data.frame(unique(df$ID))
colnames(Pat) <- 'ID'
Pat.Criteria_Type <- as.data.frame(unique(df[c('ID', criteria.string)]))
Pat$CriteriaMet <- sapply(Pat$ID, FUN = function(x){
       setequal(Pat.Criteria_Type[Pat.Criteria_Type$ID == x,],
       as.data.frame(CriteriaList))
       })
Pat <- Pat[which(Pat$CriteriaMet),]
df[df$ID %in% Pat$ID,]
    }
    
Criteria.Match(df, items, 'values')
R 字符串 列表 数据帧 比较

评论


答:

1赞 zx8754 11/30/2022 #1

table,然后使用 rowSums 进行子集:

x <- table(df)[, unlist(items) ]
rownames(x)[ which(rowSums(x) == 3) ]
# [1] "3" "4"
1赞 Michael Schulte 12/13/2022 #2

根据 items 中的值对 df 中的项进行子集。然后,循环浏览每个 ID 并检查筛选的 df 的行数是否等于项目列表的长度。然后过滤掉 FALSE 值,并将子集 df 仅作为过滤后的 df 中存在的 id。

df <- df[df$values %in% items,]
for(id in df$ID){
  df_filter <- df %>% filter(ID == id)
  df_filter$Criteria[df_filter$ID == id] <- nrow(unique(df_filter %>% select(values))) >= length(items)
      }
df_filter <- df_filter %>% filter(Criteria == TRUE)
df <- df[df$ID %in% df_filter$ID,]