Как выполнить вычисления после разделения набора данных на несколько наборов данных?

Я хочу взять набор данных и разделить его на несколько наборов данных. Для упрощенного варианта задачи. На самом деле у меня будут тысячи строк, но я хотел бы упростить задачу для понимания. Предположим, у вас есть следующий код:

vec = c(1:10)
df = data.frame(vec)
df
   vec
1    1
2    2
3    3
4    4
5    5
6    6
7    7
8    8
9    9
10  10

Я хотел бы разбить этот набор данных на строки по 5 наблюдений в каждой, а затем получить среднее значение для каждых 5 строк.

До сих пор я пытался разделить код следующим образом:

splitdf = split(df, rep(1:2,each = 5))

Теперь я хотел бы получить среднее значение каждой группы. Например, среднее значение первого фрагмента равно 3, а второго фрагмента — 8.

Затем я хотел бы выполнить функцию повторения и сохранить ее в отдельном столбце. Я хочу, чтобы мой фрейм данных выглядел следующим образом:

   vec  mean
1    1     3
2    2     3
3    3     3
4    4     3
5    5     3
6    6     8
7    7     8
8    8     8
9    9     8
10  10     8

Мне было интересно, будет ли уместна функция цикла или есть более простой способ решить эту проблему. Я открыт для предложений.


person Saneea Mustafa    schedule 06.10.2019    source источник


Ответы (3)


Нет необходимости разделять данные, если вы используете ту же логику разделения, что и группа. Например, в ave

df$mean <- ave(df$vec, rep(1:2,each = 5)) 
df

#   vec mean
#1    1    3
#2    2    3
#3    3    3
#4    4    3
#5    5    3
#6    6    8
#7    7    8
#8    8    8
#9    9    8
#10  10    8

Функция по умолчанию в ave уже является mean, поэтому мы не применяем ее явно здесь.

person Ronak Shah    schedule 06.10.2019

Просто добавьте, если вы хотите работать с разделенным фреймом данных, вот как вы можете это сделать.

# Your vector
vec = c(1:10)

# your dataframe
df = data.frame(vec)

# Your split df 
splitdf = split(df, rep(1:2,each = 5))

# -------------------------------------------------------------------------
#initialize a list (avg) with the size of splitdf 
avg <- vector("list", length(splitdf))
# loop through each list and compute the mean and assign each to avg
for (i in seq_along(splitdf)){
  avg[[i]] <- mean(splitdf[[i]]$vec)
}
# avg
# [[1]]
# [1] 3
# 
# [[2]]
# [1] 8
# unlist avg and create a column mean on df
df$mean <- rep(unlist(avg), each=5)
# df
#     vec mean
# 1    1    3
# 2    2    3
# 3    3    3
# 4    4    3
# 5    5    3
# 6    6    8
# 7    7    8
# 8    8    8
# 9    9    8
# 10  10    8
person deepseefan    schedule 06.10.2019

Вы, вероятно, ищете by(), который в основном предлагает функциональность раздельного применения. Неразделить с помощью rbind().

res <- do.call(rbind, 
               by(DF, rep(1:2, each=5), function(x) 
                 cbind(x, mean=colMeans(x))  # perform calculations on subsets
                 )
               )
res
#      vec mean
# 1.1    1    3
# 1.2    2    3
# 1.3    3    3
# 1.4    4    3
# 1.5    5    3
# 2.6    6    8
# 2.7    7    8
# 2.8    8    8
# 2.9    9    8
# 2.10  10    8

Данные

DF <- structure(list(vec = 1:10), class = "data.frame", row.names = c(NA, 
-10L))
person jay.sf    schedule 06.10.2019