如何创建将不同的过滤器应用于数据帧的循环

时间:2018-07-10 19:53:02

标签: r

我事先表示歉意,我的问题标题可能无法准确描述我要做什么。我认为我需要创建一个循环,但是我会给出更多细节。我有两个数据帧

df1

chr location gene sample1 sample2 
1 12345 FAM1 0.1 0
1 124353 ABCA 1 0.5
2 12353 ALMS1 2 0.1
3 23456 TNN 0 0
7 657864 MYBC3 0.3 1

和df2

sucrose fructose glucose galactose
FAM1 FAM2 ALMS1 ALMS2
FAM2 TNN2 MYBC3 ABCA
FAM3 MYBC2 TNN ABCA2
FAM4 MYBC ABCA2 FAM3
FAM5 ALMS2 ABCA3 FAM4

因此df1是我的主要数据帧,而df2包含用于过滤df1的列。因此,例如,我将使用df2(蔗糖)的第一列,并为蔗糖列中的任何基因过滤df1。因此,在应用过滤器后,数据将如下所示。

chr location gene sample1 sample2 
1 12345 FAM1 0.1 0

所以我已经能够做到这一点,但是真正的df2具有数千列。所以我要做的是一些如何创建循环? (如果这是正确的术语),它将贯穿df2中的所有列,将它们作为过滤器应用于df1,然后将结果另存为新的数据帧。理想情况下,我希望新数据框具有与过滤它的列相同的名称,因此在示例中,我给出的新数据框看起来像这样

sucrose
#   chr location gene sample1 sample2
# 1   1    12345  FAM1   0.1       0  

这是我仅在df2中的一列上运行的脚本的示例

sucrose <- df1 %>%
  filter(gene %in% df2[[1]]) %>%
  filter(gene != "")

sucrose$Number.of.MMVD.dogs <- (sucrose$sample1 + sucrose$sample2)

sucrose <- sucrose  %>%
  filter(Number.of.MMVD.dogs >= 0.01)

此过滤器为我提供以下输出

sucrose
#   chr location gene sample1 sample2 Number.of.MMVD.dogs
# 1   1    12345  FAM1   0.1       0        0.1

我只是不想为我用来过滤df1的每一列都键入此内容。我知道有一个更好的方法来代替手工操作,但是我不确定该怎么做。我承认,这会创建很多数据框架,但我将它们保存在项目中。

2 个答案:

答案 0 :(得分:1)

请考虑使用"access[ing] kaggle datasets through its API using RStudio"将宽大的 df2 整形为长格式,然后使用tidyr::gather df1 加入。最后,dplyr::inner_join通过新的 sugar 列返回的数据帧,该列返回许多数据帧的一个列表,理想情况下,该列表比充斥全球环境的1,000个数据帧更易于管理:

split

如果数据框存储在命名列表中而不是作为单独的对象,则不会丢失数据框的功能:

longdf <- df2 %>%
  tidyr::gather(sugar, gene)

df1 <- df1 %>%
  dplyr::inner_join(longdf, by="gene")

df_list <- split(df1, df1$sugar)

# LIST OF THREE DATA FRAMES
df_list
# $galactose
#   chr location gene sample1 sample2     sugar
# 2   1   124353 ABCA       1     0.5 galactose

# $glucose
#   chr location  gene sample1 sample2   sugar
# 3   2    12353 ALMS1     2.0     0.1 glucose
# 4   3    23456   TNN     0.0     0.0 glucose
# 5   7   657864 MYBC3     0.3     1.0 glucose

# $sucrose
#   chr location gene sample1 sample2   sugar
# 1   1    12345 FAM1     0.1       0 sucrose

答案 1 :(得分:0)

使用

library(foreach)
library(dplyr)


df1 <- tribble(~chr, ~location, ~gene, ~sample1, ~sample2,
1, 12345, "FAM1", 0.1, 0,
1, 124353, "ABCA", 1, 0.5,
2,12353, "ALMS1", 2, 0.1,
3, 23456, "TNN", 0, 0,
7, 657864, "MYBC3", 0.3 ,1)

df2 <- tribble(
  ~sucrose, ~fructose,~ glucose,~ galactose,
  "FAM1","FAM2", "ALMS1", "ALMS2",
  "FAM2", "TNN2", "MYBC3", "ABCA",
  "FAM3", "MYBC2", "TNN" ,"ABCA2",
  "FAM4", "MYBC", "ABCA2", "FAM3",
  "FAM5", "ALMS2", "ABCA3", "FAM4"
)

foreach(i= 1:dim(df2)[2], .combine=rbind) %do% { 
sucrose <- df1 %>%
  filter(gene %in% df2[[i]]) %>%
  filter(gene != "")
sucrose$Number.of.MMVD.dogs <- (sucrose$sample1 + sucrose$sample2)
sucrose <- sucrose  %>%
  filter(Number.of.MMVD.dogs >= 0.01)
} -> your_variable

,输出为:

# A tibble: 4 x 6
    chr location gene  sample1 sample2 Number.of.MMVD.dogs
  <dbl>    <dbl> <chr>   <dbl>   <dbl>               <dbl>
1  1.00    12345 FAM1    0.100   0                   0.100
2  2.00    12353 ALMS1   2.00    0.100               2.10 
3  7.00   657864 MYBC3   0.300   1.00                1.30 
4  1.00   124353 ABCA    1.00    0.500               1.50