【问题标题】:R - Calculate the differences in the column values between rows/ observations (all combinations)R - 计算行/观察值之间的列值差异(所有组合)
【发布时间】:2021-10-23 18:37:08
【问题描述】:

我有一个 R 数据框,如下例所示。我希望计算观察值/行(所有组合)之间列值的差异。

my_df <- tibble(a=runif(5), b=runif(5), c=runif(5))

> my_df
# A tibble: 5 x 3
       a     b      c
   <dbl> <dbl>  <dbl>
1 0.0513 0.267 0.846 
2 0.614  0.683 0.937 
3 0.230  0.700 0.0651
4 0.671  0.110 0.901 
5 0.424  0.520 0.817 

我已经尝试了下面的代码,它只给了我后续行之间的区别;我想要所有组合:row2 - row1;第 3 行 - 第 1 行;第4行-第1行,第5行-第1行,第3行-第2行,第4行-第2行,依此类推……

另外,我写的代码对我来说似乎不是最好的(!),虽然它输出了我希望的结果,但不是所有可能的组合!

my_diff <- as.data.frame(diff(as.matrix(my_df)))
> my_diff
           a           b           c
1  0.5623574  0.41522579  0.09165630
2 -0.3837289  0.01755953 -0.87209740
3  0.4407068 -0.58982681  0.83540813
4 -0.2463205  0.40943495 -0.08358985

如果有人可以提供帮助以使用 R 解决我的问题,我将不胜感激,如果可能的话,使用 tidy verse 选项。

谢谢。

【问题讨论】:

标签: r dataframe tidyr difference


【解决方案1】:

更新:一个整洁友好的解决方案:

library(tidyverse)
set.seed(1)
my_df <- tibble(a=runif(5), b=runif(5), c=runif(5))

给予:

# A tibble: 5 x 3
      a      b     c
  <dbl>  <dbl> <dbl>
1 0.266 0.898  0.206
2 0.372 0.945  0.177
3 0.573 0.661  0.687
4 0.908 0.629  0.384
5 0.202 0.0618 0.770

从那里开始:

my_df %>%
  mutate(ID = row_number()) %>%
  slice(as.numeric(t(combn(1:nrow(.), 2)))) %>%
  mutate(group = rep(1:(n()/2), 2)) %>%
  group_by(group) %>%
  summarize(comparison = paste0(ID[2], "-", ID[1]),
            across(c(a, b, c), ~ .[2] - .[1])) %>%
  select(-group)

给出:

# A tibble: 10 x 4
   comparison       a       b       c
   <chr>        <dbl>   <dbl>   <dbl>
 1 2-1         0.107   0.0463 -0.0294
 2 3-1         0.307  -0.238   0.481 
 3 4-1         0.643  -0.269   0.178 
 4 5-1        -0.0638 -0.837   0.564 
 5 3-2         0.201  -0.284   0.510 
 6 4-2         0.536  -0.316   0.208 
 7 5-2        -0.170  -0.883   0.593 
 8 4-3         0.335  -0.0317 -0.303 
 9 5-3        -0.371  -0.599   0.0828
10 5-4        -0.707  -0.567   0.386  

【讨论】:

  • 感谢您分享您的方法 :) 我很感激。
  • @FCL 查看我的更新以完全整洁的方式。
  • 看起来不错,谢谢。假设我有多个列,那么我将使用across(-comparison, ~.[2] - .[1]))。我在我的df中试过了,效果很好。感谢您的帮助
  • 差不多。应该是across(-c(ID), …)。此外,如果答案是您正在寻找的答案,请点赞并将其标记为您接受的答案。
  • 不错的解决方案,但需要as.numeric 吗?我认为这就够了:slice(t(combn(nrow(.), 2))).
【解决方案2】:

如果这是您所期待的,请告诉我。

my_df <- tibble(a=runif(5), b=runif(5), c=runif(5))

# Generating the sequence to calculate the combinations
seq1 <- seq(1,nrow(my_df)) 
seq2 <- seq1

# Generating the Combinations
Combinations <- expand.grid(seq1, seq2)
# Removing the dupilicate Combinations
Combinations <- Combinations[which(Combinations$Var2 < Combinations$Var1),]

# Performing the subtraction
result <- my_df[Combinations$Var1,] - my_df[Combinations$Var2,]

根据评论更新:

result <- expand.grid(seq1,seq1)%>%
  filter(Var1 > Var2)%>%
  mutate(my_df[Var1,] - my_df[Var2,])

【讨论】:

  • 是的,这正是我所期待的。非常感谢 :) 我想知道是否存在一个更加用户友好、更整洁的版本来执行此操作。感谢您的帮助。
  • 看看这个(整洁版),但我不确定这是否对用户友好:)
  • 感谢@Sunilkumar Raghuraman :)
  • 创建Combinations 的简单方法是t(combn(nrow(my_df),2))。这里只有两个区别Var1Var2,结果是一个矩阵。
猜你喜欢
  • 2019-06-03
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
  • 2021-10-16
  • 2019-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多