根据重复的行设置data.table

时间:2017-03-23 08:39:24

标签: r data.table row subset

我有一个存储在对象ddf中的数据表列表(示例如下所示):

 [[43]]
    V1 V2 V3
1:  b  c  a
2:  b  c  a
3:  b  c  a
4:  b  c  a
5:  b  b  a
6:  b  c  a
7:  b  c  a

 [[44]]
   V1 V2 V3
1:  a  c  a
2:  a  c  a
3:  a  c  a
4:  a  c  a
5:  a  c  a

 [[45]]
   V1 V2 V3
1:  a  c  b
2:  a  c  b
3:  a  c  b
4:  a  c  b
5:  a  c  b
6:  a  c  b
7:  a  c  b
8:  a  c  b
9:  a  c  b
               .............and so on till [[100]]

我想要对列表ddf进行子集,以便结果只包含ddf:

  1. 每个至少有9行
  2. 9行中的每一行都相同
  3. 我想存储此子设置输出
  4. 我已经为此写了一些代码:

     for(i in 1:100){
     m=(as.numeric(nrow(df[[i]]))>= 9)
     if(m == TRUE & df[[i]][1,] = df[[i]][2,] = 
     =df[[i]][3,] =df[[i]][4,] =df[[i]][5,] =df[[i]][6,]=
     df[[i]][7,]=df[[i]][8,]=df[[i]][9,]){
     print(df[[i]])
     }}
    

    请告诉我什么是错的&如何根据“n”个相似的行来推广子设置的结果。

    [后续问题]

        Answer obtained from Main question:
        > ddf[sapply(ddf, function(x) nrow(x) >= n & nrow(unique(x)) == 1)]
          $`61`
             V1 V2 V3
          1:  a  c  b
          2:  a  c  b
          3:  a  c  b
          4:  a  c  b
          5:  a  c  b
          6:  a  c  b
          7:  a  c  b
    
          $`68`
             V1 V2 V3
          1:  a  c  a
          2:  a  c  a
          3:  a  c  a
          4:  a  c  a
          5:  a  c  a
          6:  a  c  a
          7:  a  c  a
          8:  a  c  a
    
          $`91`
             V1 V2 V3
          1:  b  c  a
          2:  b  c  a
          3:  b  c  a
          4:  b  c  a
          5:  b  c  a
          6:  b  c  a
          7:  b  c  a
    
                   ..... till the last data.frame which meet the row matching criteria (of at least 9 similar rows)
    
          There are only 2 types of elements in the list: 
                      **[[.. ]]**        
         **Case 1.** >70% accuracy       
         **Case 2.** <70% accuracy       
    

    您会注意到上面“跟进问题”中显示的输出是

    $'61',$'68'&amp; $ '91',但其他数据帧没有输出与“匹配行”标准不匹配。

    我需要一个输出,其中这些与输出条件不匹配的缺失值会产生“输出不良”的输出。

    因此,最终列表应与输入列表的长度相同。

    通过使用粘贴并排放置它们我应该能够看到每个输出。

2 个答案:

答案 0 :(得分:2)

我们可以遍历list(&#39; ddf&#39;),只有duplicate行的子集(duplicated),order数据集, if数据集的行数&#39; x1&#39;大于8,然后得到前9行(head(x1, 9))或else返回错误结果&#39;印刷

lapply(ddf, function(x) {
  x1 <- x[duplicated(x)|duplicated(x, fromLast=TRUE)]
if(nrow(x1)>9) {
 x1[order(V1, V2, V3), head(.SD, 9)] 

  } else "bad answer"
 })
#[[1]]
#   V1 V2 V3
#1:  b  c  a
#2:  b  c  a
#3:  b  c  a
#4:  b  c  a
#5:  b  c  a
#6:  b  c  a
#7:  b  c  a
#8:  b  c  a
#9:  b  c  a

#[[2]]
#[1] "bad answer"

#[[3]]
#[1] "bad answer"

数据

ddf <- list(data.table(V1 = 'b', V2 = rep(c('c', 'b', 'c'), c(8, 1, 2)), V3 = 'a'),
       data.table(V1 = rep("a", 5), V2 = rep("c", 5), V3 = rep("a", 5)),
       data.table(V1 = c('b', 'a', 'b', 'b'), V2 = c('b', 'a', 'c', 'b'),
       V3 = c("c", "d", "a", "b")))

答案 1 :(得分:2)

ddf是您的数据表列表时,则:

ddf[sapply(ddf, nrow) >= 9 & sapply(ddf, function(x) nrow(unique(x))) == 1]

应该给你想要的结果。

其中:

  • sapply(ddf, nrow) >= 9检查数据表是否有九行或更多行
  • sapply(ddf, function(x) nrow(unique(x))) == 1检查所有行是否相同。

或者@docendodiscimus提出一个sapply来电:

ddf[sapply(ddf, function(x) nrow(x) >= 9 & nrow(unique(x)) == 1)]

或者使用.N特殊符号和uniqueN的{​​{1}}函数:

data.table

另一种选择是使用ddf[sapply(ddf, function(x) x[,.N] >= 9 & uniqueN(x) == 1)] (根据评论中@Frank的建议):

Filter

获取数据表编号的两种方法:

1。使用Filter(function(x) nrow(x) >= 9 & uniqueN(x) == 1, ddf)

which

2. :为列表中的数据表指定名称:

which(sapply(ddf, function(x) nrow(x) >= 9 & nrow(unique(x)) == 1))

现在输出将在输出中包含数据表编号:

names(ddf) <- paste0('dt', 1:length(ddf))