【问题标题】:Filter_at() not working with -starts_with()Filter_at() 不适用于 -starts_with()
【发布时间】:2019-08-08 08:20:48
【问题描述】:

我有一个包含多个样本(列)和变量(行)的数据集。我想过滤掉一个数据集,以确定一组特定样本所独有的变量。

这是示例数据框

dput(df)
structure(list(Description=c("k__Bacteria;__;__;__;__","k__Bacteria;p__Acidobacteria;c__[Chloracidobacteria];o__RB41;f__Ellin6075", 
"k__Bacteria;p__Acidobacteria;c__Acidobacteriia;o__Acidobacteriales;f__Koribacteraceae", 
"k__Bacteria;p__Acidobacteria;c__DA052;o__Ellin6513;f__", "k__Bacteria;p__Acidobacteria;c__Solibacteres;o__Solibacterales;f__", 
"k__Bacteria;p__Actinobacteria;c__Acidimicrobiia;o__Acidimicrobiales;f__", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Actinomycetaceae", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Actinopolysporaceae", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Corynebacteriaceae"
), ADZU.3 = c(2651L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 12L), ADZU.4 = c(2439L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 5L), BEP.3 = c(11452L, 9L, 5L, 
0L, 0L, 6L, 14L, 0L, 0L, 83L), BEP.4 = c(4168L, 0L, 0L, 9L, 3L, 
0L, 0L, 5L, 6L, 61L), Hya.1 = c(15179L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 94L), Hya.2 = c(4525L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
34L)), row.names = c(NA, 10L), class = "data.frame")

我在 dyplr 中使用 filter_at() 函数,并且有一个按预期工作的代码。下面,我有许多以不同字母 A、B、H 等开头的样本。我想找到以相同字母(例如字母 B)开头的样本所独有的变量。

我有一个目前运行良好的代码

##code set 1, this code works

df.bep<-filter_at(df,vars(starts_with("A"),starts_with("H")), 
all_vars(.==0))

这段代码的结果如下,这是我期望看到的:

dput(df.bep)
structure(list(Description = c("k__Bacteria;p__Acidobacteria;c__[Chloracidobacteria];o__RB41;f__Ellin6075", 
"k__Bacteria;p__Acidobacteria;c__Acidobacteriia;o__Acidobacteriales;f__Koribacteraceae", 
"k__Bacteria;p__Acidobacteria;c__DA052;o__Ellin6513;f__", "k__Bacteria;p__Acidobacteria;c__Solibacteres;o__Solibacterales;f__", 
"k__Bacteria;p__Actinobacteria;c__Acidimicrobiia;o__Acidimicrobiales;f__", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Actinomycetaceae", 
"k__Bacteria;p__Actinobacteria;c__Actinobacteria;o__Actinomycetales;f__Actinopolysporaceae"
), ADZU.3 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), ADZU.4 = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L), BEP.3 = c(9L, 5L, 0L, 0L, 6L, 14L, 
0L, 0L), BEP.4 = c(0L, 0L, 9L, 3L, 0L, 0L, 5L, 6L), Hya.1 = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L), Hya.2 = c(0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L)), row.names = c(NA, -8L), class = "data.frame")

这个问题是,对于具有许多不同样本的较长数据集,为我想要 filter_at() 的每个样本指定每个字母开始变得很麻烦。

我修改了脚本以使用-starts_with() 尝试通过排除以我不想过滤的特定字母开头的样本来过滤数据框(例如过滤除以字母 B 开头的所有样本),如:

df.bep.2<-filter_at(df,vars(-starts_with("B")),all_vars(.==0))

但是,这第二组代码没有按预期工作。我没有收到任何错误,而是得到一个空数据框

dput(df.bep.2)
structure(list(Description = character(0), ADZU.3 = integer(0), 
ADZU.4 = integer(0), BEP.3 = integer(0), BEP.4 = integer(0), 
Hya.1 = integer(0), Hya.2 = integer(0)), row.names = c(NA, 
0L), class = "data.frame")

在组合 filter_at() 和 -starts_with() 时,我需要在代码中添加一些额外的内容吗?

【问题讨论】:

  • 您能否提供一个您的df 样本,用于重现您的问题?
  • 如何提供样本数据集?
  • 如果您的数据集足够小,请使用dput(df) 的输出修改您的问题。如果数据集很大,请确定仍然产生此问题的最小子集并改为发布。更多信息:stackoverflow.com/a/5963610/300187
  • 谢谢@ArtemSokolov 我已经更新了我的问题以包含示例数据和输出

标签: r filtering tidyr startswith


【解决方案1】:

这意味着您在all_vars 中的条件在不以"A" 开头的列中不满足。该过滤器正在搜索所有不以 A 开头的列,并且只选择包含所有 0 的行。

例如,mtcars 数据集不会在这种情况下返回任何内容:

mtcars %>%
  filter_at(vars(-starts_with("q")), all_vars(. == 0))

 [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
<0 rows> (or 0-length row.names)

除非我们添加一个只有0 的行(尽管我们可以为qsec 列添加一个非零值):

mtcars %>%
  bind_rows(setNames(rep(0, ncol(.)), names(.))) %>%
  filter_at(vars(-starts_with("q")), all_vars(. == 0))

  mpg cyl disp hp drat wt qsec vs am gear carb
1   0   0    0  0    0  0    0  0  0    0    0

编辑:对于您的具体问题,这是因为Description 列没有== 0。可能有几个解决方案,但下面有两个应该适合你!

df1 %>%
  filter_at(vars(-starts_with("B"), -one_of("Description")), all_vars(. == 0))

df1 %>%
  filter_if(sapply(., is.numeric) & !startsWith(names(.), "B"), all_vars(. == 0))

【讨论】:

  • 谢谢你的回答安德鲁。我已经用示例数据和预期输出更新了我的问题。如您所见,第一个脚本确实按照我的意图进行,即通过将它们从具有 0 值的其他样本中过滤掉以某个字母开头的样本中的唯一变量。您是否会说两组代码(第一组具有starts_with(),第二组具有-starts_with())本质上应该执行相同的过程?我认为他们应该是,但是他们实际上在做根本不同的事情而我错了吗?
  • @student001,刚刚添加了一个编辑——希望它有所帮助!如果您还有其他问题,请告诉我!
  • 谢谢安德鲁!第一种表示法有效(我没有尝试第二种表示法,但我确信它也有效)。你能解释一下 %>% 是做什么的吗?我从未见过这种表示法,但它似乎一直与 dyplr 中的 filter() 函数一起使用
  • @student001,好问题。它被称为管道——在几种编程语言中都有管道,但这是由 magrittr 包引入的(它使用 dplyr 加载。可以认为是“然后”。正如您所指出的,当使用 dplyr / tidyverse 中的函数。如果您想了解更多信息,请参阅 R for Data Science 中的一章。这是一本很棒的介绍书(不仅仅是那一章)。
  • 感谢安德鲁的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
  • 2022-12-21
  • 1970-01-01
相关资源
最近更新 更多