Выбрать столбец во фрейме данных на основе NA в строках
Скажем, у меня есть фрейм данных из 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]])))
Первое размещение. Обычно я могу собрать то, что мне нужно, с этого сайта. Заранее спасибо.
2 ответа
Я думаю, что вы могли бы сохранить выполнение этого цикла дважды с помощью простого 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"
Я не уверен, что ваш код обеспечит то, что, как вы думаете, должно быть, если 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