Использование apply (), но получение ответа из списка классов - PullRequest
0 голосов
/ 04 июня 2018

У меня есть ряд столбцов в data.frame, из которых я хотел бы получить последнее значение, исключая любые NA.Для этого я использую функцию:

    last_value <- function(x) tail(x[!is.na(x)], 1)

Я использую apply() для работы этой функции по 13 столбцам для каждого наблюдения (по строке).

    df$LastVal<-apply(df[,c(116, 561, 1006, 1451, 1896, 2341, 2786, 3231, 
    3676, 4121, 4566, 5011, 5456)], 1, FUN=last_value)

Моя проблема заключается в том, что выходные данные отображаются в виде списка 5336 (всего наблюдений), а не просто вектора последних значений по строке.Ответы, похоже, есть, но опять же в виде списка.Я использовал эту функцию раньше, и она работала нормально.Когда я str() мои столбцы, они все целые числа.Может ли эта функция сработать, если нет значений и есть только NA?

Я должен добавить, что когда я unlist() новую переменную, я получаю сообщение об ошибке, в котором говорится, что "замена имеет 4649 строк, данные имеют 5336", поэтому я думаю, что это может иметь какое-то отношение к NA.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Во-первых, вам нужно посмотреть, что выводится функцией last_value, как вы ее определили, с помощью строки NA значений.

last_value <- function(x) tail(x[!is.na(x)], 1)

df <- matrix(1:24, 4)
df[2, ] <- NA
df <- as.data.frame(df)
apply(df, 1, last_value)
#[[1]]
#V6 
#21 
#
#[[2]]
#named integer(0)
#
#[[3]]
#V6 
#23 
#
#[[4]]
#V6 
#24

Проблема в том, что второй членэтот список имеет нулевую длину.Это означает, что unlist не решит проблему.
Вы должны проверить значение нулевой длины.

last_value <- function(x) {
  y <- tail(x[!is.na(x)], 1)
  if(length(y) == 0) NA else y
}
apply(df, 1, last_value)
#[1] 21 NA 23 24
0 голосов
/ 04 июня 2018

Вы можете включить свою функцию в выборку.

Пример

df <- as.data.frame(matrix(1:12, 3, 4))
> df
  V1 V2 V3 V4
1  1  4  7 10
2  2  5  8 11
3  3  6  9 12

last_value <- function(x) tail(x[!is.na(x)], 1)

> df[, last_value(c(3, 4))]  # selects last column
[1] 10 11 12

Тест с NA.

df[2, 4] <- NA
> df[, last_value(c(3, 4))]
[1] 10 NA 12

Если вам нужен подход apply(), используйте хорошо объясненный ответ @Rui Barradas.Если вы зависите от скорости, рассмотрите эталонный тест обоих решений:

Unit: microseconds
                      expr     min       lq      mean  median       uq     max neval cld
  apply(df, 1, last_value) 166.095 172.6005 182.09241 177.449 188.2925 257.179   100   b
 df[, last_value(c(3, 4))]  32.147  33.4230  36.12764  34.699  35.5920 131.396   100  a 

Кстати, для колонного использования sapply().

> sapply(df[, c(3, 4)], FUN=last_value)
V3 V4 
 9 12 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...