Szukali, ale nie widziałem, gdzie to zostało obsługiwane

   x y value
1  2 1     5
2  3 1     4
3  4 1     6
4  5 1     3
5  3 2     5
6  4 2     7
7  5 2     3
8  4 3     2
9  5 3     5
10 5 4     7

Gdzie X i Y są sparowane witrynami i wartością jest różnica. Chciałbym uzyskać wyniki średniej dla każdej witryny wyświetlanych oddzielnie. Na przykład. Średnia strona wszystkich witryn 5 par (5 | 3, 5 | 4, 5 | 1, 5 | 2) = 4.5, aby moje wyniki były jak poniżej:

site    avg 
   1    4.5
   2    5
   3    4
   4    5.5
   5    4.5

Czyj ma rozwiązanie?

r
3
blackie 2 czerwiec 2018, 10:22

3 odpowiedzi

Najlepsza odpowiedź

Rozwiązanie przy użyciu dplyr i mapply.

library(dplyr)

data.frame(site = unique(c(df$x, df$y))) %>%
  mutate(mean =  mapply(function(v)mean(df$value[df$x==v | df$y==v]), .$site)) %>%
  arrange(site)

#   site mean
# 1    1  4.5
# 2    2  5.0
# 3    3  4.0
# 4    4  5.5
# 5    5  4.5

Dane:

df <- read.table(text = 
"  x y value
1  2 1     5
2  3 1     4
3  4 1     6
4  5 1     3
5  3 2     5
6  4 2     7
7  5 2     3
8  4 3     2
9  5 3     5
10 5 4     7",
header = TRUE, stringsAsFactors = FALSE)
1
MKR 2 czerwiec 2018, 11:43

Oto kolejna opcja z tidyverse

library(tidyverse)
df %>% 
   select(x, y) %>% 
   unlist %>% 
   unique %>% 
   sort %>% 
   tibble(site = .) %>% 
   mutate(avg = map_dbl(site, ~
             df %>% 
               filter_at(vars(x, y), any_vars(. == .x)) %>% 
               summarise(value = mean(value)) %>%
               pull(value)))
# A tibble: 5 x 2
#   site  avg
#  <int> <dbl>
#1     1   4.5
#2     2   5  
#3     3   4  
#4     4   5.5
#5     5   4.5

Dane

df <- structure(list(x = c(2L, 3L, 4L, 5L, 3L, 4L, 5L, 4L, 5L, 5L), 
    y = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L), value = c(5L, 
    4L, 6L, 3L, 5L, 7L, 3L, 2L, 5L, 7L)), .Names = c("x", "y", 
"value"), class = "data.frame",
   row.names = c("1", "2", "3", 
"4", "5", "6", "7", "8", "9", "10"))
2
akrun 2 czerwiec 2018, 15:00

Jeśli nazwimy oryginalny przykład danych jako df:

df$site_pair <- paste(df$x, df$y, sep = "-")
all_sites <- unique(c(df$x, df$y))
site_get_mean <- function(site_name) {
  yes <- grepl(site_name, df$site_pair)
  mean(df$value[yes])
}

df.new <- data.frame(site = all_sites, 
                     avg = sapply(all_sites, site_get_mean))

Wynik: (Edytowany na zamówienie według nazwy witryny)

> df.new[order(df.new$site), ]
  site avg
5    1 4.5
1    2 5.0
2    3 4.0
3    4 5.5
4    5 4.5
1
J. Win. 2 czerwiec 2018, 16:20