2017-08-14 8 views
1

私が持っているデータには、3つの固有のIDを持つ3つの変数があり、それぞれに複数のレコードがあります。 zの値が0(負)を下回っている場合、各IDについてRの特定の行以下のすべてのレコードを除外します

ID <- c(rep(1,7), rep(2,6), rep(3,5), rep(4,6)) 
t <- c(seq(1,7), seq(1,6), seq(1,5), rep(2,6)) 
y <- c(rep(6,7), rep(1,6), rep(6,5), rep(0.2,6)) 
z <- c(5,0,0,0,1,0,0,0,0,-1,0,0,0,4,2,NaN,0,1,0,0,1,Inf,Inf, Inf) 
dat1 <- data.frame(ID, t, y, z) 

下記参照は、NaN、Infの、または-Infは、私はそのレコードとその下のすべてのレコードを除外する必要があります。このデータについては

、新しい処理されたデータは次のようになります。これはあなたのサンプルデータで動作します

ID <- c(rep(1,7), rep(2,2), rep(3,2), rep(4,3)) 
t <- c(seq(1,7), seq(1,2), seq(1,2), rep(2,3)) 
y <- c(rep(6,7), rep(1,2), rep(6,2), rep(0.2,3)) 
z <- c(5,0,0,0,1,0,0,0,0,4,2,0,0,1) 
dat2 <- data.frame(ID, t, y, z) 

答えて

6

aveでこれを行うことができます。その後、削除のために、後続の行を識別するためにcumsumカウンタを使用した:

dat1[with(dat1, ave(z < 0 | (!is.finite(z)), ID, FUN=cumsum) == 0),] 

クイックチェックすると、彼らはrownamesを除いて、一致見ていない並ん:

all.equal(
    dat2, 
    dat1[with(dat1, ave(z < 0 | (!is.finite(z)), ID, FUN=cumsum) == 0),], 
    check.attributes=FALSE 
) 
#[1] TRUE 
+0

'cummin'と本質的に同じです。' dat1 [as.logical(ave(dat1 $ z、dat1 $ ID、FUN = function(x)cummin(is.finite(x)&x> = 0))) '。あなたの議論をもっと近づけることによって少しきれいにすることができます。 – lmo

0

。おそらく最速の解決策ではないでしょう。あなたのID列が昇順にソートされている場合は

mutate(dat1, rownumber = 1:nrow(dat1)) -> dat1 

for(i in unique(dat1$ID)) { 
    firstMiss = min(filter(dat1, ID==i & 
          (z %in% c(NaN, Inf, -Inf) | 
           z < 0))$rownumber, 
        max(filter(dat1, ID==i)$rownumber)+1, 
        na.rm=TRUE) 
    dat1 <- filter(dat1, !(ID==i & rownumber >= firstMiss)) 
} 
dat2 <- select(dat1, -rownumber) 
2

あなたはグループごとの代替として、

dat2 <- dat1[unlist(tapply(dat1$z, dat1$ID, function(x) 
      cumsum(x<0 | x %in% c(NaN, -Inf, Inf))==0)),] 

dat2 
    ID t y z 
1 1 1 6.0 5 
2 1 2 6.0 0 
3 1 3 6.0 0 
4 1 4 6.0 0 
5 1 5 6.0 1 
6 1 6 6.0 0 
7 1 7 6.0 0 
8 2 1 1.0 0 
9 2 2 1.0 0 
14 3 1 6.0 4 
15 3 2 6.0 2 
19 4 2 0.2 0 
20 4 2 0.2 0 
21 4 2 0.2 1 
+1

これはIDが順番にソートされていることに依存しています。 'dat1 $ ID == 2、]、dat1 [dat1 $ ID!= 2]]'に対して 'dat1 < - rbind>に対して試してください。 – thelatemail

+0

はい - 'tapply'は、それらを要素として扱い、それらをソートします。私は上記の警告を含んでいます。ありがとう。あなたの解決策は 'ave'で良いです。 –

0

をジャストlaffsため:

library(dplyr) 
dat1 %>% group_by(ID) %>% 
     mutate(non_positive = min(which(lead(z,1) < 0 | 
           !is.finite(lead(z,1)) | row_number() == n()))) %>% 
     filter(row_number() <= non_positive) %>% 
     select(-non_positive) 

# # A tibble: 14 x 4 
# # Groups: ID [4] 
#  ID  t  y  z 
# <dbl> <dbl> <dbl> <dbl> 
# 1  1  1 6.0  5 
# 2  1  2 6.0  0 
# 3  1  3 6.0  0 
# 4  1  4 6.0  0 
# 5  1  5 6.0  1 
# 6  1  6 6.0  0 
# 7  1  7 6.0  0 
# 8  2  1 1.0  0 
# 9  2  2 1.0  0 
# 10  3  1 6.0  4 
# 11  3  2 6.0  2 
# 12  4  2 0.2  0 
# 13  4  2 0.2  0 
# 14  4  2 0.2  1 
関連する問題