棘手的多步子集选择

时间:2013-01-19 16:18:52

标签: r matrix

我有一个矩阵:

1 3  NA
1 2  0
1 7  2
1 5  NA
1 9 5
1 6  3
2 5  2
2 6  1
3 NA  4
4 2  9
...

我想为第一列中每个数字选择那些元素,第二列中的相应值在其第二列中具有NA。

所以搜索将采用以下方式:

  1. 在第一列中查找数字:1。
  2. 检查第二栏中的相应值:3,2,7,5,9,6 ......
  3. 在第一栏中查找3,2,7,5,9,6并查看他们是否有NA 第二栏
  4. 上述案例的结果将是:

    >3 NA  4<
    

    因为这是唯一在其第二行中具有NA的值。

    这就是我想用文字做的事情:

    1. 查看第一栏中的数字,我找到'1'。

    2. 第二栏中有1个数字:3,2,7,5,9,6

    3. 这些数字在他们自己的第二列中是否有NA?是的,3有一个NA

    4. 我希望返回这些数字而不是行号。

    5. 结果将是原始矩阵的子集,其中的行满足条件。

    6. 这将是matlab的等价物,其中i是第1列中的数字:

      isnan(matrix(matrix(:,1)==i,2))==1) 
      

3 个答案:

答案 0 :(得分:2)

使用by,按第1列的组获取结果,假设dat是您的数据框

by(dat,dat$V1,FUN=function(x){
                  y <- dat[which(dat$V1 %in% x$V2),]
                  y[is.na(y$V2),]
})

dat$V1: 1
  V1 V2 V3
9  3 NA  4
-------------------------------------------------------------------------------- 
dat$V1: 2
[1] V1 V2 V3
<0 rows> (or 0-length row.names)
-------------------------------------------------------------------------------- 
dat$V1: 3
[1] V1 V2 V3
<0 rows> (or 0-length row.names)
-------------------------------------------------------------------------------- 
dat$V1: 4
[1] V1 V2 V3
<0 rows> (or 0-length row.names)

修改

这里我试着做与matlab命令相同的功能:

这里是matlab的R等价物

  isnan(matrix(matrix(:,1)==i,2))==1)   ## what is i here 

  is.na(dat[dat[dat[,1]==1,2],])        ## R equivalent , I set i =1

     V1    V2    V3
3 FALSE FALSE FALSE
2 FALSE FALSE FALSE
7 FALSE FALSE FALSE
5 FALSE FALSE FALSE
9 FALSE  TRUE FALSE
6 FALSE FALSE FALSE

答案 1 :(得分:2)

这可以很容易地阅读,因为它遵循您描述的步骤:

idx1 <- m[, 1L] == 1L
idx2 <- m[, 1L] %in% m[idx1, 2L]
idx3 <- idx2 & is.na(m[, 2L])
m[idx3, ]
# V1 V2 V3 
#  3 NA  4

它全部被矢量化并使用整数比较,所以它不应该非常慢。但是,如果它对您的需求来说太慢,您应该使用data.table并使用第一列作为密钥。

请注意,您不需要任何作业,因此如果您正在寻找单行代码:

m[is.na(m[, 2L]) & m[, 1L] %in% m[m[, 1L] == 1L, 2L], ]
# [1]  3 NA  4

(但绝对难以阅读和维护。)

答案 2 :(得分:0)

我仍然不完全清楚你想要什么,但也许这会起作用?

m<-read.table(
textConnection("1 3  NA
1 2  0
1 7  2
1 5  NA
1 9 5
1 6  3
2 5  2
2 6  1
3 NA  4
4 2  9"))

do.call(rbind,lapply(split(m[,2],m[,1]),function(x) m[x[!is.na(x)][is.na(m[x[!is.na(x)],2])],]))

#   V1 V2 V3
# 1  3 NA  4

如果你提供一个你想拥有多行的例子会更好。