С помощью R, как я могу отделить непрерывные значения от фрейма данных с элементом NA и вычислить среднее значение только для переменной Y?

#r #dataframe #subset #na

#r #фрейм данных #подмножество #na

Вопрос:

   X Y
1 1 2
2 2 4
3 NA NA
4 NA NA
5 NA NA
6 NA NA
7 1 4
8 2 6
9 1 8
10 1 10
  

Это должно быть так: в первом случае среднее значение значений 2 и 4 равно 3, Во втором случае среднее значение значений 4,6,8,10 равно 7 и так далее…

Ответ №1:

Ваши данные:

 df = data.frame(X=c(1,2,NA,NA,NA,NA,1,2,1,1),Y=c(2,4,NA,NA,NA,NA,4,6,8,10))
  

Вы можете определить строки с последовательными строками без NAs с помощью diff(complete.cases(..)) :

 blocks = cumsum(c(0,diff(complete.cases(df)) != 0 ))

block_means = tapply(df$Y,blocks,mean)

 0  1  2 
 3 NA  7

block_means[!is.na(block_means)]
0 2 
3 7
  

Или, если вам не нужно знать порядок:

 na.omit(as.numeric(tapply(df$Y,blocks,mean)))
[1] 3 7
  

Ответ №2:

Мы можем создавать группы непрерывных значений, используя rleid from data.table , внутри каждой группы вычислять mean из Y значений/

 library(dplyr)

df %>%
  group_by(gr = data.table::rleid(is.na(Y))) %>%
  summarise(Y = mean(Y, na.rm = TRUE)) %>%
  filter(!is.na(Y)) -> df1
df1

#     gr     Y
#  <int> <dbl>
#1     1     3
#2     3     7
  

data.table способ сделать это был бы :

 library(data.table)
df1 <- setDT(df)[, .(Y = mean(Y, na.rm = TRUE)), rleid(is.na(Y))][!is.na(Y)]
  

данные

 df <- structure(list(X = c(1L, 2L, NA, NA, NA, NA, 1L, 2L, 1L, 1L), 
    Y = c(2L, 4L, NA, NA, NA, NA, 4L, 6L, 8L, 10L)), 
class = "data.frame", row.names = c(NA, -10L))
  

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

1. У меня эта ошибка: нет применимого метода для ‘filter_’, применяемого к объекту класса «логический»

2. @Kerbe Можете ли вы протестировать это на данных, опубликованных в моем сообщении? Работает ли это для этих данных?

3. @Kerbe Вы можете select выбрать нужные столбцы. Чтобы выбрать gr столбец, который вы можете сделать df1 <- df %>% group_by(gr = data.table::rleid(is.na(Y))) %>% summarise(Y = mean(Y, na.rm = TRUE)) %>% filter(!is.na(Y)) %>% select(gr) . Вывод находится в df1 .

4. Спасибо! У меня много данных в качестве входных данных, и обработка выполняется очень медленно.

5. Извините, я не понимаю вашего вопроса. В своем сообщении вы показали и упомянули только об одном фрейме данных, и мой ответ пытается ответить на вопрос для него.