根据向量列表对数据框进行子集化

时间:2021-02-28 22:44:25

标签: r dataframe

我有一个字符向量列表,称为 erase()。例如:

l

通过考虑 set.seed(42) ## for sake of reproducibility genes <- paste("gene",1:20,sep="") tot=data.frame(term=sample(genes,30, replace=T), num=sample(1:10, 30, replace=T), stringsAsFactors = FALSE) s1<-sample(genes,2, replace=F) s2<-sample(genes,4, replace=F) s3<-sample(genes,3, replace=F) s4<-sample(genes,2, replace=F) s5<-sample(genes,2, replace=F) s6<-sample(genes,3, replace=F) l=list(s1,s2,s3,s4,s5,s6) ,我得到:

tot[tot$term%in%l[[1]],]

我把

      term num
 1  gene17   4
 3   gene1   6
 7  gene17   2
 26  gene1   6

我可以得到第二列的总值,即18。对于我得到的列表的其他元素,分别为: df=tot[tot$term%in%l[[1]],] sum(df$num) 。这可以通过 for 循环来实现:

32 13 19 17 29

我想知道是否有更简单的方法来做到这一点。

2 个答案:

答案 0 :(得分:2)

可以简化为 sapply

v2 <- sapply(l, function(j) sum(tot$num[tot$term %in% j]))

-检查 OP 的循环输出

identical(v, v2)
#[1] TRUE

或者更紧凑的方式 map

library(purrr)
map_dbl(l, ~ sum(tot$num[tot$term %in% .x]))

或者用tidyverse

library(dplyr)
stack(setNames(l, seq_along(l))) %>% 
  group_by(ind) %>% 
  summarise(Sum = tot %>% 
                    filter(term %in% values) %>%
                    pull(num) %>% 
                    sum) %>%
  pull(Sum)

答案 1 :(得分:1)

这是一种tidyverse方式:

library(tidyverse)

enframe(l, value = 'term') %>%
  unnest(term) %>%
  left_join(tot, by = 'term') %>%
  group_by(name) %>%
  summarise(num = sum(num, na.rm = TRUE))

#   name   num
#* <int> <int>
#1     1    18
#2     2    32
#3     3    13
#4     4    19
#5     5    17
#6     6    29