R-Dataframe: среднее по строке на всех DF с условными на другом столбце - PullRequest
0 голосов
/ 06 октября 2019

Я начинаю с кода, который я хочу получить (все пишется с примером)

df <- data.frame(comp = c(10, 12, 14, 17, 17),
                 val = c(0, 5, 10, 15, 20),
                 cond_inf = c(8, 9.6, 11.2, 13.6, 13.6),
                 cond_sup = c(12, 14.4, 16.8, 20.4, 20.4),
                 mean_cond_text1 = c("Average of VAL lines whose COMP is between 8 12", 
                                     "Average of VAL lines whose COMP is between 9.6 14.4",
                                     "Average of VAL lines whose COMP is between 11.2 16.8",
                                     "Average of VAL lines whose COMP is between 13.6 20.4", 
                                     "Average of VAL lines whose COMP is between 13.6 20.4"),
                 mean_cond_text2 = c("(val_row1+val_row2)/2", "(val_row1+val_row2+val_row3)/3", "(val_row2+val_row3)/2", "(val_row3+val_row4+val_row5)/2", "(val_row3+val_row4+val_row5)/2)"),
                 mean_cond_text3 = c("(0+5)/2", "(0+5+10)/3", "(5+10)/2", "(10+15+20)/3", "(10+15+20)/3)"),
                 mean_cond_num = c((0+5)/2, (0+5+10)/3, (5+10)/2, (10+15+20)/3, (10+15+20)/3))

Я хочу, чтобы в каждой строке кадра данных вычислялось среднее значение столбца VAL для всех строкчьи значения сравнения COMP включены в интервал COND_INF - COND_SUP моей линии, по которой я вычисляю среднее значение. Таким образом, в каждой строке моего фрейма данных рассчитывается среднее значение.

В фрейме данных каждая строка с 4 столбцами все время заполнена

COMP = столбец, для которого будет выполнено условиеприменяется для учета этой линии или нет при расчете среднего

VAL = значение, которое будет использоваться для расчета среднего значения, если линия будет учитываться

COND_INF =нижняя граница (-20% от COMP), чья COMP должна быть выше-равной, чтобы учитываться

COND_SUP = верхняя граница (+ 20% от COMP), чья COMP должна быть ниже-равной, чтобы быть принятой ваккаунт

Спасибо, за помощь, я потерялся ...

Ответы [ 2 ]

0 голосов
/ 07 октября 2019

Спасибо за вашу помощь. С вашей идеей, я сделал

df <- data.frame(comp = c(10, 12, 14, 17, 17),
                 val = c(0, 5, 10, 15, 20),
                 cond_inf = c(8, 9.6, 11.2, 13.6, 13.6),
                 cond_sup = c(12, 14.4, 16.8, 20.4, 20.4),
                 mean_cond_num = c((0+5)/2, (0+5+10)/3, (5+10)/2, (10+15+20)/3, (10+15+20)/3))

df$id <- seq(1, nrow(df))
df2 <- sqldf("SELECT a.*, b.val as val2, b.cond_inf as cond_inf2, b.cond_sup as cond_sup2
       FROM df as a, df as b
       where a.cond_inf <= b.comp
          and a.cond_sup >= b.comp")

df3 <- df2 %>%
  group_by(id, mean_cond_num) %>%
  summarise(mmoy = mean(val2))

Это работает, я должен попробовать, если на моих реальных данных, это нормально с расчетным временем. Если все в порядке, я вернусь, чтобы решить. Спасибо

0 голосов
/ 07 октября 2019

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

Глядя на ваш фрейм данных, неясно, как были рассчитаны строки с 3 по 5. Например, строка 3 имеет comp из 14. Это должно быть в диапазоне строк 2-5, а не только 2 и 3? Ряды 4 и 5 имеют диапазон (13,6, 20,4) и должны быть включены в расчет для comp из 14? Я также получаю другое среднее значение для строк 4 и 5.

Дайте мне знать, если мое понимание неверно. Судя по моим впечатлениям, здесь есть один подход. Я подозреваю, что есть лучшие альтернативные способы использования data.table, sqldf и т. Д.

df <- data.frame(comp = c(10, 12, 14, 17, 17),
                 val = c(0, 5, 10, 15, 20),
                 cond_inf = c(8, 9.6, 11.2, 13.6, 13.6),
                 cond_sup = c(12, 14.4, 16.8, 20.4, 20.4))

library(dplyr)

# Add index for row number
df$idx <- seq(1, nrow(df))

# Split dataframe into comp and index and look up table with values and range
df1 <- df[c(1,5)]
df2 <- df[2:4]

# Expand grid to get multiple combinations and filter to those where comp in range 
expand_grid(df1, df2) %>%
  filter(between(comp, cond_inf, cond_sup)) %>%
  group_by(idx) %>%
  mutate(mean_cond_num = mean(val)) %>%
  right_join(df)

   comp   idx   val cond_inf cond_sup mean_cond_num
  <dbl> <int> <dbl>    <dbl>    <dbl>         <dbl>
1    10     1     0      8       12             2.5
2    12     2     5      9.6     14.4           5  
3    14     3    10     11.2     16.8          12.5
4    17     4    15     13.6     20.4          17.5
5    17     5    20     13.6     20.4          17.5
...