3

過去の投稿と回答を読むことで非常に助けになっているstackoverflowコミュニティの新年の悩み(これが私の最初の質問です)。回避策を見つけましたが、他のアプローチ/解決策が提案されるのではないかと思います。

大きいから末尾のNAを削除しようとしてdata.frameいますが、これらのNAはのいくつかの列にのみ表示され、data.frameすべての列を出力に保持したいと思います。これが代表的なデータサブセットです。

df=data.frame(var1=rep("A", 8), var2=c("a","b","c","d","e","f","g","h"), var3=c(0,1,NA,2,3,NA,NA,NA), var4=c(0,0,NA,4,5,NA,NA,NA), var5=c(0,0,NA,0,2,4,NA,NA))

プロセスの目標:

  1. var3、var4、およびvar5のNAの存在に基づいて後続のNAをトリミングします
  2. 最終出力のすべての列を保持します
  3. 末尾のNAのみを削除します(つまり、行3はプレースホルダーとして記録に残ります)
  4. すべての列にNAがある場合にのみトリミングします(つまり、行7と8で、行6ではありません)

これらの目標に基づいて、ソリューションはdfの最後の2行を削除する必要があります。

df.output = df[-c(7,8),]

(zooパッケージ内の)na.trimの動作は理想的であり(data.frameの最後にあるsides = "right"のNAに削除が制限されるため)、私の回避策にはna.trimの変更が含まれます。サブセット用語を含めるための.default関数。

助言がありますか?助けてくれてありがとう。

編集:この質問を完了するために、以下はna.trim.defaultコードから作成した関数です。これも機能しますが、前述のように、zooパッケージをロードする必要があります。

na.trim.multiplecols <-  function (object, colrange, sides = c("both", "left", "right"),     is.na = c("any","all"),...) 
{
is.na <- match.arg(is.na)
nisna <- if (is.na == "any" || length(dim(object[,colrange])) < 1) {
complete.cases(object[,colrange])
}
else rowSums(!is.na(object[,colrange])) > 0
idx <- switch(match.arg(sides), left = cumsum(nisna) > 0, 
            right = rev(cumsum(rev(nisna) > 0) > 0), both = (cumsum(nisna) > 
                                                               0) &       rev(cumsum(rev(nisna)) > 0))
if (length(dim(object)) < 2) 
object[idx]
else object[idx, , drop = FALSE]

}
4

2 に答える 2

1

に基づく何かmax(which(!is.na()))が機能します。これを使用して、対象の列から欠測データの最大のインデックスを見つけます。

dfを使用する

ind <-  max(max(which(!is.na(df$var3))),
        max(which(!is.na(df$var4))),        
        max(which(!is.na(df$var5)))) 

df[1:ind, ]

   var1 var2 var3 var4 var5
 1    A    a    0    0    0
 2    A    b    1    0    0
 3    A    c   NA   NA   NA
 4    A    d    2    4    0
 5    A    e    3    5    2
 6    A    f   NA   NA    4
于 2015-06-03T02:01:25.613 に答える
0

Edit:rleベースとを使用した最初のソリューションapply

t <- rle(apply(as.matrix(df[,3:5]), 1, function(x) all(is.na(x))))
r <- ifelse(t$values[length(t$values)] == TRUE, t$lengths[length(t$lengths)], 0)
head(df, -r)

Rlefromパッケージを使用した2番目のソリューションIRanges

require(IRanges)
t <- min(sapply(df[,3:5], function(x) {
    o <- Rle(x)
    val <- runValue(o)
    if (is.na(val[length(val)])) {
        len <- runLength(o)
        out <- len[length(len)]
    } else {
        out <- 0
    }
}))
head(df, -t)
于 2013-01-03T17:27:07.953 に答える