【问题标题】:Filter out observations present in specific pairs of samples in R过滤掉 R 中特定样本对中存在的观察值
【发布时间】:2018-02-15 02:16:03
【问题描述】:

我有一个与样本相关的观察结果列表。我想删除特定样本对中出现的相同观察结果。

数据示例:

sample observation
sample1A 5
sample1B 7
sample2A 10
sample2B 10
sample3A 10
sample3B 5

因此,我们的想法是根据字母 A 和 B 将样本分组成对,然后为每一对删除任何具有匹配观察值的行。

在上述情况下,只有来自 sample2A 和 sample 2B 的观察结果将被排除,因为它们来自同一个样本 sample2,在两个不同的场合(sample2A 和 sample 2B)采样。输出如下所示:

sample observation
sample1A 5
sample1B 7
sample3A 10
sample3B 5

如果可以使用 DPLYR 来做到这一点,那将更加有用,因为我正在努力提高我对它的熟练程度。

我想使用 group_by() 根据样本名称将数据分组,然后使用 filter() 可以工作,但我不确定如何处理基于正则表达式或字符串的第一次配对的嵌套条件,然后通过查找行之间的匹配值进行过滤。

提前感谢您的帮助。

【问题讨论】:

  • 这将是超级简单的 3 个变量:sampleNum、sampleLet、observation。然后做dat[with(dat, !(duplicated(sampleNum & observation) | duplicated(sampleNum & observation, FromLast=TRUE)),]
  • 如果我可以将数据复制到 R...Lke 一个向量或矩阵中,那将是一个更好的问题。

标签: r filter dplyr


【解决方案1】:

我们可以通过删除'sample'中的最后一个字符然后根据唯一'observation'的数量filter来创建一个组,即如果length大于1,我们保留它

library(dplyr)
df2 %>%
  group_by(grp = sub("[A-Z]$", "", sample)) %>%
  filter(n_distinct(observation)>1) %>% 
  ungroup() %>% 
  select(-grp)
# A tibble: 4 x 2
#    sample observation
#      <chr>       <int>
#1 sample1A           5
#2 sample1B           7
#3 sample3A          10
#4 sample3B           5

数据

df2 <- structure(list(sample = c("sample1A", "sample1B", "sample2A", 
"sample2B", "sample3A", "sample3B"), observation = c(5L, 7L, 
10L, 10L, 10L, 5L)), .Names = c("sample", "observation"),
 class = "data.frame", row.names = c(NA, -6L))

【讨论】:

    【解决方案2】:

    带有循环的基础解决方案。

    # create data
    dat <- c(5,7,10,10,10,5)
    names(dat) <- c('sample1A', 'sample1B', 'sample2A', 'sample2B', 'sample3A', 'sample3B')
    dat
    
    # lets go
    pairs <- substr(names(dat), 1, nchar(names(dat))-1)
    single <- unique(pairs)
    
    new_dat <- NULL
    for(i in 1:length(single)){
      pos <- pairs == single[i]
      if(!any(duplicated(dat[pos]))){
        new_dat <- c(new_dat, dat[pos])
      }
    }
    
    new_dat
    

    【讨论】:

      【解决方案3】:

      如果您的格式是常规格式,您也可以这样做:

      df %>% filter(matrix(.$observation,2) %>% {.[1,]!=.[2,]} %>% rep(each=2))
      

      只有底座,并且尽可能短:

      df[rep(!!diff(matrix(df[[2]],2)),each=2),]
      
      #     sample observation
      # 1 sample1A           5
      # 2 sample1B           7
      # 5 sample3A          10
      # 6 sample3B           5
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多