Взять пример данных, глядя на количество осадков с показаниями температуры в двух местах:
temps <- data.frame(
rainfall = c(1, 1, 1, 2, 2, 2, 3, 3, 3),
loc1 = c(77.5, 77.8, 81.2, 82.2, 80.6, 75.9, 77.6, 78.3,
81.5),
loc2 = c(79.3, 74.2, 74.9, 77.5, 79.9, 80.1, 82.6, 80.3,
78.7)
)
Цель состоит в том, чтобы получить статистику по этим данным, сгруппированную по температуре, округленной до ближайшего градуса. Однако мы хотим, чтобы данные были сгруппированы независимо от местоположения, то есть для группы 80
, это может быть температура, которая округляется до 80 при loc1
или loc2
.
Конечно, вы можете выполнять группировку и суммирование по каждому столбцу независимо, а затем агрегировать, например, что-то вроде
lapply(c('loc1', 'loc2'), function(loc) {
temps %>% group_by(temp = round(!!sym(loc))) %>%
summarize(loc,
mean = mean(rainfall),
median = median(rainfall)
)
})
Это будет работать для простого среднего арифметического как для loc1
, так и для loc2
, но не для большинства других статистических данных, таких как медиана, стандартное отклонение и т. Д., Потому что вам остается в основном статистика для подмножеств данных, а не в целом интересующие данные.
Другими словами, мы ищем условие: «группируйте данные по округленным значениям по всем столбцам местоположения, а не только по одному за раз, так что заданная округленная температура существует по крайней мере в одном из столбцов». Таким образом, если температура округляется до 80 хотя бы в одном из loc1
, loc2
, этот ряд включается в группу на 80.
Я ищу способ достижения этого, который хорошо масштабируется для очень больших наборов данных.
edit: Вот грубый способ найти ожидаемый результат:
temps2 <- temps %>%
mutate_at(vars(matches('loc')), round)
bind_rows(lapply(sort(unique(unlist(temps2[,c('loc1', 'loc2')]))),
function(deg) {
temps2 %>% filter(loc1 == deg | loc2 == deg) %>%
summarize(deg,
mean = mean(rainfall),
median = median(rainfall))
}))
deg mean median
1 74 1.000000 1.0
2 75 1.000000 1.0
3 76 2.000000 2.0
4 78 2.000000 2.0
5 79 2.000000 2.0
6 80 2.333333 2.0
7 81 1.500000 1.5
8 82 2.500000 2.5
9 83 3.000000 3.0
Это соответствует ответу Калума ниже.