2

假设我有一个 7 列的数据框,其中一些行有 7 个值,而另一些行的 NA 超过了某个点。我想获取不是 NA 的最后一个值(从左到右),然后直接获取左侧的值。它是分层数据,但有些组比其他组更深入。我想要新数据框中两列中最深和第二深的组。

这段代码有效,但会最大限度地利用我对 46K 观察数据帧的记忆。有没有我没有想到的更有效的方法?

df <- data.frame(LEVEL1 = c('animal', 'vegetable', 'mineral'),
                 LEVEL2 = c('mammal', 'pepper', 'rock'),
                 LEVEL3 = c('dog', 'jalepeno', NA),
                 LEVEL4 = c('westie', NA, NA))

deepest <- apply(df, 1, 
                  function(x) length(which(!is.na(x))))
one.up <- apply(df, 1, 
                    function(x) length(which(!is.na(x)))-1)
len <- nrow(df)
output <- data.frame(one.up = unlist(sapply(1:len, 
                            function(x) df[x, one.up[x]])),
                     deepest= unlist(sapply(1:len, 
                                            function(x) df[x, deepest[x]])))

第一次发帖。通常我可以从这个站点拼凑出我需要的东西。提前致谢。

4

2 回答 2

3

apply我认为您可以通过一个简单的调用来保存两次运行该循环,例如:

> apply(df, 1, function(x) {
+     n <- max(which(!is.na(x)))
+     x[(n-1):n]
+ })
     [,1]     [,2]       [,3]     
[1,] "dog"    "pepper"   "mineral"
[2,] "westie" "jalepeno" "rock"   
于 2012-06-04T23:11:13.750 回答
1

如果 NA 可能散布在行的长度中(尽管您说这不应该发生),我不确定您的代码是否会提供您认为应该的内容。此代码将在第一个 NA 之前停止并返回两个先前的值。

> output.m <- apply(df,1,function(x) { leng.na <-rle(is.na(x))$lengths[1]
                                       tail(x[1:leng.na],2) }  )
> output.d <- as.data.frame(t(output.m))
> output.d
       V1       V2
1     dog   westie
2  pepper jalepeno
3 mineral     rock
于 2012-06-04T23:15:57.797 回答