Условное деление и агрегация - PullRequest
1 голос
/ 15 апреля 2020

Рассмотрим следующий фрейм данных:

d <- data.frame(a = c("01","02"),
                b = c(100,200),
                c = c(200,400))

И следующий фрейм данных:

agg <- data.frame(d = c("01","01","02","02"),
                  e = c("V1","V2","V1","V3"))

Я хочу изменить столбец a в d, используя agg. То есть, если a = 01, его следует изменить на V1 и так далее. Однако в некоторых случаях некоторые a в d входят в несколько имен в e в agg. Например, 01 и 02 входят в V1. В этом случае я хочу рассчитать среднее. То есть я хочу, чтобы мой окончательный набор данных был таким:

    a   b    c    
1   V1  150  300
2   V2  100  200
3   V3  200  400

Как видно, V1 - это в среднем 01 и 02.

Как я могу это сделать в R ?

1 Ответ

2 голосов
/ 15 апреля 2020

Скучная старая база R ответа. Как прокомментировано:

Основой c logi c будет слияние / соединение на agg$d -to- d$a - затем агрегирование результатов на e после слияния.

aggregate(cbind(b,c) ~ e, data=merge(agg, d, by.x="d", by.y="a"), FUN=mean)
#   e   b   c
#1 V1 150 300
#2 V2 100 200
#3 V3 200 400

В мире dplyr применяется то же самое:

library(dplyr)
agg %>% 
  left_join(d, by=c("d"="a")) %>%
  select(-d) %>%
  group_by(e) %>%
  summarise_all(list(mean))
## A tibble: 3 x 3
#  e         b     c
#  <fct> <dbl> <dbl>
#1 V1      150   300
#2 V2      100   200
#3 V3      200   400

И data.table для хорошей меры:

library(data.table)
setDT(d)
setDT(agg)
d[agg, on="a==d"][, lapply(.SD, mean), by=e, .SDcols=-"a"]
#    e   b   c
#1: V1 150 300
#2: V2 100 200
#3: V3 200 400
...