选择包含多个X非零连续值的行

时间:2017-05-17 15:09:54

标签: r subset

我有一个包含年份,特征和物种的元素矩阵。但我想只选择某些连续存在一年的物种。我可以通过查看表格看到这一点:

mat = matrix(c(2000,2001,2001,2002,2002,2003, 2004, 2005,
               2001,
               2000, 2001, 2002,  2005,
               2000, 2002, 2004, 2004,  2006,
               2,3,3,4,1,2,2,2,
               2,
               1,4,4,3,
               1,4,4,3,2,
               "sp1","sp1","sp1","sp1","sp1","sp1","sp1","sp1",
               "sp2",
               "sp3","sp3","sp3","sp3",
               "sp4","sp4","sp4","sp4","sp4"), nrow = 18)
mat = as.data.frame(mat)
colnames(mat) = c("yr","trait","sp")
res = table(mat$sp,mat$yr)

这里的表格如下:

      2000 2001 2002 2003 2004 2005 2006
  sp1    1    2    2    1    1    1    0
  sp2    0    1    0    0    0    0    0
  sp3    1    1    1    0    0    1    0
  sp4    1    0    1    0    2    0    1
  1. 但是在这里,我想从我的分析中删除sp2,因为它在2001年只见过一次而没有其他年份。有没有办法做到这一点?我试过这个,但它打印完全相同的表:

    res[apply(res,1,function(z) any(z==0)),]
    

    最后我想从'mat'数据中删除sp2,但是使用表中的信息来删除sp2。

          2000 2001 2002 2003 2004 2005 2006
      sp1    1    2    2    1    1    1    0
      sp3    1    1    1    0    0    1    0
      sp4    1    0    1    0    2    0    1
    

    'themat'看起来像:

         yr trait  sp
    1  2000     2 sp1
    2  2001     3 sp1
    3  2001     3 sp1
    4  2002     4 sp1
    5  2002     1 sp1
    6  2003     2 sp1
    7  2004     2 sp1
    8  2005     2 sp1
    10 2000     1 sp3
    11 2001     4 sp3
    12 2002     4 sp3
    13 2005     3 sp3
    14 2000     1 sp4
    15 2002     4 sp4
    16 2004     4 sp4
    17 2004     3 sp4
    18 2006     2 sp4
    
  2. 另外,我想要一个第二个命令,允许我选择在2年或更长时间内连续看到的'''的个体(这会删除sp4,因为它只在偶数年才被看到)。

    同样,我试过这个,但它并没有删除正确的信息:

    mat[which(res != 0),]
    

    最终结果将是:

          2000 2001 2002 2003 2004 2005 2006
      sp1    1    2    2    1    1    1    0
      sp3    1    1    1    0    0    1    0
    

    'themat'看起来像:

         yr trait  sp
    1  2000     2 sp1
    2  2001     3 sp1
    3  2001     3 sp1
    4  2002     4 sp1
    5  2002     1 sp1
    6  2003     2 sp1
    7  2004     2 sp1
    8  2005     2 sp1
    10 2000     1 sp3
    11 2001     4 sp3
    12 2002     4 sp3
    13 2005     3 sp3
    
  3. 这适用于更大的数据集。这只是一个小例子。

3 个答案:

答案 0 :(得分:1)

我认为您不需要res table对数据框mat执行过滤,您可以使用dplyr直接进行过滤。 为了过滤掉仅出现一年的给定sp,您可以执行以下操作:

library(dplyr)
mat %>% group_by(yr) %>% group_by(sp) %>% filter(n_distinct(yr)>1) %>% ungroup()

  yr  trait     sp
   <fctr> <fctr> <fctr>
1    2000      2    sp1
2    2001      3    sp1
3    2001      3    sp1
4    2002      4    sp1
5    2002      1    sp1
6    2003      2    sp1
7    2004      2    sp1
8    2005      2    sp1
9    2000      1    sp3
10   2001      4    sp3
11   2002      4    sp3
12   2005      3    sp3
13   2000      1    sp4
14   2002      4    sp4
15   2004      4    sp4
16   2004      3    sp4
17   2006      2    sp4

为了过滤掉连续两年没有出现的sps,你可以这样做:

mat %>% group_by(sp)%>% filter(min(diff(sort(unique(yr))))==1)

返回

yr  trait    sp
   <dbl> <fctr> <chr>
1      1      2   sp1
2      2      3   sp1
3      2      3   sp1
4      3      4   sp1
5      3      1   sp1
6      4      2   sp1
7      5      2   sp1
8      6      2   sp1
9      1      1   sp3
10     2      4   sp3
11     3      4   sp3
12     6      3   sp3

请注意,最后一个操作会返回一个警告,因为sp2只有一年。您可以结合上述两个操作:

mat %>% group_by(yr) %>% group_by(sp) %>% filter(n_distinct(yr)>1) %>% ungroup() %>% group_by(sp)%>% filter(min(diff(sort(unique(yr))))==1)

哪个不会返回警告。

编辑:如果您想根据指定的连续年份数(而不仅仅是2年)进行过滤,您可以这样做:

## This function returns the max number of consecutive 1s +1 in a vector, and 0 if there are none or there is just one value in the vector
consec1=function(x){ifelse((1 %in% x),max(rle(x)$lengths[rle(x)$values==1])+1,0)}
## Then use it in your dplyr::filter
mat %>% group_by(sp) %>% filter(consec1(diff(sort(unique(yr))))==6)

返回:

 yr  trait     sp
  <dbl> <fctr> <fctr>
1  2000      2    sp1
2  2001      3    sp1
3  2001      3    sp1
4  2002      4    sp1
5  2002      1    sp1
6  2003      2    sp1
7  2004      2    sp1
8  2005      2    sp1

答案 1 :(得分:0)

  1. 我有点不情愿但是:

    self.videoVRView.removeFromSuperview()
    self.videoVRView = nil
    parent?.addSubview(self.videoVRView)`
    
  2. RES [!申请(RES,1,find_zeros)]

    屈服于:

     find_zeros<-function(vec){
        bool<-grepl("1{3}",paste(ifelse(vec==0,1,0),collapse = ""),perl = T)  
        return(bool)
     }
    

    当然为了获得修剪 2000 2001 2002 2003 2004 2005 2006 sp1 1 2 2 1 1 1 0 sp3 1 1 1 0 0 1 0 sp4 1 0 1 0 2 0 1 ,应该使用:

    mat

答案 2 :(得分:0)

复制您的数据:

mat = matrix(c(2000,2001,2001,2002,2002,2003, 2004, 2005,
               2001,
               2000, 2001, 2002,  2005,
               2000, 2002, 2004, 2004,  2006,
               2,3,3,4,1,2,2,2,
               2,
               1,4,4,3,
               1,4,4,3,2,
               "sp1","sp1","sp1","sp1","sp1","sp1","sp1","sp1",
               "sp2",
               "sp3","sp3","sp3","sp3",
               "sp4","sp4","sp4","sp4","sp4"), nrow = 18)
mat = as.data.frame(mat)
colnames(mat) = c("yr","trait","sp")
res = table(mat$sp,mat$yr)

问题一:

将布尔矩阵乘以1将为您提供可以使用rowSums()的内容。

res <- res[which(rowSums(1*(res!=0))>1),]
res

会给你:

      2000 2001 2002 2003 2004 2005 2006
  sp1    1    2    2    1    1    1    0
  sp3    1    1    1    0    0    1    0
  sp4    1    0    1    0    2    0    1

问题二:

您可以使用rle()来检测游程长度。

res <- res[apply(res, 1, function(x) any(rle(x)$lengths > 1)),]
res

会给你:

      2000 2001 2002 2003 2004 2005 2006
  sp1    1    2    2    1    1    1    0
  sp3    1    1    1    0    0    1    0