将成对值分离为各个变量的行/列

时间:2018-06-02 07:22:33

标签: r

已搜索但尚未查看此处理的位置。我有一个成对计算数据框,项目中的网站之间存在绝对差异,数据是这样的

   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

其中x和y是配对站点,值是差异。我想分别显示每个网站的平均值的结果。例如。网站平均所有网站5对(5 | 3,5 | 4,5 | 1,5 | 2)= 4.5,以便我的结果如下:

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

谁得到了解决方案?

3 个答案:

答案 0 :(得分:2)

以下是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

数据

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"))

答案 1 :(得分:1)

如果我们将原始数据示例命名为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))

结果:(按网站名称编辑)

> 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

答案 2 :(得分:1)

使用dplyrmapply的解决方案。

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

数据:

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)