【问题标题】:Take Symmetrical Mean of a tibble (ignoring the NAs)取 tibble 的对称平均值(忽略 NA)
【发布时间】:2021-06-02 09:04:58
【问题描述】:

我有一个小标题,其中行和列是相同的 ID,我想取平均值(忽略 NA)以使 df 对称。我正在努力看看如何。

data <- tibble(group = LETTERS[1:4], 
               A = c(NA, 10, 20, NA),
               B = c(15, NA, 25, 30),
               C = c(20, NA, NA, 10),
               D = c(10, 12, 15, NA)
               )

我通常会这样做

A <- as.matrix(data[-1])
(A + t(A))/2

但由于 NA,这不起作用。

编辑:下面是预期的输出。

output <- tibble(group = LETTERS[1:4],
                 A = c(NA, 12.5, 20, 10),
                 B = c(12.5, NA, 25, 21),
                 C = c(20, 25, NA, 12.5),
                 D = c(10, 21, 12.5, NA))

【问题讨论】:

  • 你的预期输出是什么?
  • 可能先是A[is.na(A)] &lt;- 0,然后是(A + t(A))/2
  • 没有。这不起作用,因为在取平均值时你将非 NA 值减半

标签: r dplyr tidyverse data-processing symmetric


【解决方案1】:

这是使用 tidyverse 代码的建议。

library(tidyverse)

data <- tibble(group = LETTERS[1:4], 
               A = c(NA, 10, 20, NA),
               B = c(15, NA, 25, 30),
               C = c(20, NA, NA, 10),
               D = c(10, 12, 15, NA)
)

A <- data %>% 
  pivot_longer(-group, values_to = "x")

B <- t(data) %>% 
  as.data.frame() %>% 
  setNames(LETTERS[1:4]) %>% 
  rownames_to_column("group") %>% 
  pivot_longer(-group, values_to = "y") %>% 
  left_join(A, by = c("group", "name")) %>% 
  mutate(
    mean = if_else(!(is.na(x) | is.na(y)), (x + y)/2, x),
    mean = if_else(is.na(mean) & !is.na(y), y, mean)
    ) %>% 
  select(-x, -y) %>% 
  pivot_wider(names_from = name, values_from = mean)

B

## A tibble: 4 x 5
#  group     A     B     C     D
#  <chr> <dbl> <dbl> <dbl> <dbl>
#1 A      NA    12.5  20    10  
#2 B      12.5  NA    25    21  
#3 C      20    25    NA    12.5
#4 D      10    21    12.5  NA  

【讨论】:

    【解决方案2】:

    好的,这就是我最终这样做的方式。如果我不使用 for 循环,我会更喜欢,因为我拥有的实际数据要大得多,但乞丐不能选择!

    A <- as.matrix(data[-1])
    
    for (i in 1:nrow(A)){
      for (j in 1:ncol(A)){
        if(is.na(A[i,j])){
          A[i,j] <- A[j, i]
        }
      }
    }
    
    output <- (A + t(A))/2
    output %>% 
      as_tibble() %>% 
      mutate(group = data$group) %>% 
      select(group, everything())
    
    
    # A tibble: 4 x 5
      group     A     B     C     D
      <chr> <dbl> <dbl> <dbl> <dbl>
    1 A      NA    12.5  20    10  
    2 B      12.5  NA    25    21  
    3 C      20    25    NA    12.5
    4 D      10    21    12.5  NA 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-27
      • 2019-08-19
      • 2020-03-28
      • 2021-04-16
      • 1970-01-01
      • 2021-05-01
      • 2017-08-28
      相关资源
      最近更新 更多