#r
#r
Вопрос:
Я хотел бы рассчитать «интервал значений, отличных от NA», для разных столбцов.
Вот набор данных:
temp <- data.frame(
date = seq(as.Date("2018-01-01"), by = 'month', length.out = 12),
X1 = c(100, NA, 23, NA, NA, 12, NA, NA, NA, NA, NA, 100),
X2 = runif(12, 50, 100),
X3 = c(24, NA, NA, NA, NA, 31, 1, NA, 44, NA, 100, NA),
X4 = NA
)
Например, X1
имеет интервалы, отличные от NA, как 1, 2, 5
, что означает, что от 100 до 23 между этими двумя значениями, отличными от NA, находится 1 NA, от 23 до 12 между этими двумя значениями, отличными от NA, есть 2 NAs, а от 12 до 100 между этими двумя значениями 5 NAsзначения, отличные от NA.
Ожидаемый результат:
result <- data.frame(
X1_inv_mean = mean(c(1, 2, 5)),
X1_inv_median = median(c(1, 2, 5)),
X1_inv_sd = sd(c(1, 2, 5)),
X2_inv_mean = mean(0),
X2_inv_median = median(0),
X2_inv_sd = sd(0),
X3_inv_mean = mean(c(4, 1, 1, 1)),
X3_inv_median = median(c(4, 1, 1, 1)),
X3_inv_sd = sd(c(4, 1, 1, 1)),
X4_inv_mean = NA,
X4_inv_median = NA,
X4_inv_sd = NA
)
>result
X1_inv_mean X1_inv_median X1_inv_sd X2_inv_mean X2_inv_median X2_inv_sd X3_inv_mean X3_inv_median X3_inv_sd
1 2.666667 2 2.081666 0 0 NA 1.75 1 1.5
X4_inv_mean X4_inv_median X4_inv_sd
1 NA NA NA
Спасибо за помощь!
Комментарии:
1. Результат не обязательно точно такой же, как в сообщении, просто с аналогичным результатом будет оценен по достоинству.
2. X1 имеет интервалы, отличные от NA, как 1, 2, 5 … почему?? Что вы подразумеваете под интервалами, отличными от NA ?
3. Обратите внимание, что
X4
существует 12 последовательныхNA
секунд, и поэтому ваш желаемый результат неверен (при условии, что я правильно вас понял).4. @Sotos, я обновил сообщение, так что, надеюсь, я лучше объяснил это вам.
5. @markus Для
X4
да, я ожидаю, что это будетNA
для столбца ALL-NA.
Ответ №1:
Базовый параметр R
out <- lapply(temp[-1], function(x) {
if(all(is.na(x))) {
tmp <- NA
} else {
tmp <- with(rle(is.na(x)), lengths[values])
c(mean = mean(tmp),
median = median(tmp),
sd = sd(tmp))}
})
as.data.frame(out)
# X1 X2 X3 X4
#mean 2.666667 NaN 1.75 NA
#median 2.000000 NA 1.00 NA
#sd 2.081666 NA 1.50 NA
Использование rle
следующей строки дает вам значения NA
s для каждого столбца
tmp <- with(rle(is.na(x)), lengths[values])
Например, для столбца X1
with(rle(is.na(temp$X1)), lengths[values])
#[1] 1 2 5
Затем мы вычисляем вашу итоговую статистику для каждого tmp
.
Если все значения в столбце NA
равны, функция возвращает NA
.
Комментарии:
1. Я получаю результат для исходного набора данных. Ответ идеальный! Здесь у меня есть дополнительный вопрос, что означает это
lengths[values]
? Я понимаюwith()
, и его аргументы, кроме того, результатrle
дает список, содержащийlengths
иvalues
, но я не могу связать результат rle с этимlengths[values]
. Спасибо!2. @J.D Как вы заметили,
rle()
возвращает объект с двумя компонентами:lengths
иvalues
. В приведенном выше примере последний является логическим вектором. Использованиеwith
позволяет оценивать эти компоненты в локальной среде. То есть нам не нужно сначала присваивать результатrle
имени, а затем манипулировать его значениями, мы можем сделать это за один раз. Посколькуvalues
имеет логический тип, чтоlengths[values]
возвращает только те значенияlengths
, для которыхvalues
естьTRUE
. То жеr <- rle(is.na(temp$X1)); r$lengths[r$values]
самое, что и — просто приятнее читать для интерактивного использования.
Ответ №2:
Обновление: для переменных n столбцов:
command <- ""
summaryString <- ""
for(i in colnames(temp)){
if(i != "date"){
print(i)
summaryString <- paste(summaryString,i,"_inv_mean = mean(",i,", na.rm = T),",sep="")
summaryString <- paste(summaryString,i,"_inv_median = median(",i,", na.rm = T),",sep="")
summaryString <- paste(summaryString,i,"_inv_sd = sd(",i,", na.rm = T),",sep="")
}
command <- paste("output <- temp %>% summarise(",substr(summaryString, 0, nchar(summaryString)-1),")",sep="")
}
eval(parse(text=command))
Использование dplyr:
library(dplyr)
output <- temp%>%
summarise(x1_inv_mean = mean(X1, na.rm = T),
x1_inv_median = median(X1, na.rm = T),
x1_inv_sd = sd(X1, na.rm = T),
x2_inv_mean = median(X2, na.rm = T),
x2_inv_median = mean(X2, na.rm = T),
x2_inv_sd = sd(X2, na.rm = T),
x3_inv_mean = median(X3, na.rm = T),
x3_inv_median = mean(X3, na.rm = T),
x3_inv_sd = sd(X3, na.rm = T),
x4_inv_mean = mean(X4, na.rm = T),
x4_inv_median = median(X4, na.rm = T),
x4_inv_sd = sd(X4, na.rm = T))