Функция R max игнорирует NA

#r #max

#r #макс

Вопрос:

Ниже приведен рабочий код. Когда я реплицирую одни и те же данные в другом наборе данных, я получаю ошибки:(

 #max by values
df <- data.frame(age=c(5,NA,9), marks=c(1,2,7), story=c(2,9,NA))
df

df$colMax <- apply(df[,1:3], 1, function(x) max(x[x != 9],na.rm=TRUE))
df
  

Я пытался сделать то же самое для больших данных, и я получаю предупреждения, почему?

 maindata$max_pc_age <- apply(maindata[,c(paste("Q2",1:18,sep="_"))], 1, function(x) max(x[x != 9],na.rm=TRUE))


50: In max(x[x != 9], na.rm = TRUE) :
  no non-missing arguments to max; returning -Inf
  

чтобы лучше понять проблему, я внес изменения, как показано ниже, но все еще получаю предупреждения

 maindata$max_pc_age <- apply(maindata[,c(paste("Q2",1:18,sep="_"))], 1, function(x) max(x,na.rm=TRUE))
1: In max(x, na.rm = TRUE) : no non-missing arguments to max; returning -Inf
  

Комментарии:

1. Можете ли вы выяснить проблему из результата max(numeric(0)) , или вам нужно больше объяснений?

2. все еще нужна помощь… Я попробовал class(numeric(0)), и он вернул numeric .. не должна ли функция max работать с ним?

3. Это работает . Если в векторе нет элементов, каково максимальное значение? Вы запрашиваете максимальное количество значений, которые не равны 9 и не являются NA . По-видимому, иногда это ничего не оставляет.

4. @joran: максимум ничего не очевидно -Inf .

5. Да, большое. Весь ваш вектор будет состоять из символов, а не из чисел.

Ответ №1:

Похоже, что проблема уже была указана в комментариях. Поскольку некоторые векторы содержат только NA s, -Inf сообщается, что я беру из комментариев, которые вам не нравятся. В этом ответе я хотел бы указать на один из возможных способов решения проблемы, а именно на встроенный оператор управления (вместо перезаписи -Inf после факта, что в равной степени справедливо). Например,

  my.max <- function(x) ifelse( !all(is.na(x)), max(x, na.rm=T), NA)
  

выполняет этот трюк. Если каждый ( all ) элемент в x является NA , то NA возвращается, а max в противном случае. Если вы хотите вернуть любое другое значение, просто замените NA на это значение. Вы также можете легко встроить это в свою apply -функцию. Например.

  maindata$max_pc_age <- apply(maindata[,c(paste("Q2",1:18,sep="_"))], 1, my.max)
  

Меня все еще иногда смущает R NA и обработка пустого набора. Такие операторы, как test <- NA; test==NA выдадут NA в результате (вместо TRUE , возвращаемого is.na(test) ), что иногда рационализируется тем, что, поскольку значение отсутствует, как вы могли узнать, что эти два отсутствующих значения идентичны? В этом случае, однако, max возвращает -Inf , поскольку ему задан пустой набор, который, я думаю, совсем не очевиден. Мой опыт показывает, что, если появляются странные и неожиданные результаты, NA часто задействуются s или пустые наборы.

Ответ №2:

В случаях, подобных приведенным ниже:

 df[2,2] <- NA
df[1,2] <- -5

apply(df, 1, function(x) max(x[x != 9],na.rm=TRUE))
#[1]    5 -Inf    7
#Warning message:
#In max(x[x != 9], na.rm = TRUE) :
#  no non-missing arguments to max; returning -Inf
  

Вы могли бы сделать:

 df1 <- df  
minVal <- min(df1[!is.na(df1)])-1

df1[is.na(df1)|df1==9] <- minVal
val <- do.call(`pmax`, df1)
val[val==minVal] <- NA
val
#[1]  5 NA  7
  

Комментарии:

1. 1 для pmax / pmin, хотя можно было бы разработать более эффективные методы, когда передается только один немаркированный аргумент, исключающий все это do.call . Вы можете перегрузить ее, чтобы сделать na.rm=T значение по умолчанию, или вы можете сказать, do.call(pmax, c(df1, list(na.rm=T)) .

Ответ №3:

Вы можете использовать, hablar::max_ который возвращает NA , если все значения NA

 apply(df, 1, function(x) hablar::max_(x[x!=9]))
#[1]  5 NA  7
  

данные

 df <- structure(list(age = c(5, NA, 9), marks = c(-5, NA, 7), story = c(2, 
9, NA)), row.names = c(NA, -3L), class = "data.frame")

df
#  age marks story
#1   5    -5     2
#2  NA    NA     9
#3   9     7    NA