首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分组并减去数据帧中的所有行。

分组并减去数据帧中的所有行。
EN

Stack Overflow用户
提问于 2020-01-22 18:48:26
回答 5查看 163关注 0票数 0

请考虑以下示例:

代码语言:javascript
复制
t1 t2 t3 t4 t5 t6 
A  4  6  7  8  5
A  3  6  8  1  4
A  2  3  5  3  1
A  3  4  3  1  3
B  3  6  8  3  4
B  3  9  3  7  3
B  5  2  3  2  1

我希望得到一个数据帧,它检查组内每对可能的行之间的差异(A和B分别)。

我一直在尝试基于循环对数据进行子集,并手动计算行之间的差异。这导致了大量的计算,在计算了所有差异之后,很难对引用进行管理。我基本上得到了几份名单。

生成的数据文件需要包含所有可能的行组合(或排列?)的行差异。在一群人中。

例如,对于B,不考虑第一列即字符,以下是预期的结果:

代码语言:javascript
复制
t2 t3 t4 t5 t6
0  -3  5 -4  1
-2  4  5  1  3
-2  7  0  5  2 

这个标志不是很重要。只有震级

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2020-01-22 19:14:02

这里有一种方法可以得到一个有一行的表,它显示了每个组中每对行之间的差异。例如,该输出的第2行显示输入的第1行减去输入的第3行。

代码语言:javascript
复制
library(data.table)
setDT(df) # convert to data.table

df[, {  pairs <- CJ(row1 = 1:.N, row2 = 1:.N)[row1 != row2]
        data.table(pairs + .I[1] - 1, .SD[pairs[[1]]] - .SD[pairs[[2]]])
  }, by = t1]



#     t1 row1 row2 t2 t3 t4 t5 t6
#  1:  A    1    2  1  0 -1  7  1
#  2:  A    1    3  2  3  2  5  4
#  3:  A    1    4  1  2  4  7  2
#  4:  A    2    1 -1  0  1 -7 -1
#  5:  A    2    3  1  3  3 -2  3
#  6:  A    2    4  0  2  5  0  1
#  7:  A    3    1 -2 -3 -2 -5 -4
#  8:  A    3    2 -1 -3 -3  2 -3
#  9:  A    3    4 -1 -1  2  2 -2
# 10:  A    4    1 -1 -2 -4 -7 -2
# 11:  A    4    2  0 -2 -5  0 -1
# 12:  A    4    3  1  1 -2 -2  2
# 13:  B    5    6  0 -3  5 -4  1
# 14:  B    5    7 -2  4  5  1  3
# 15:  B    6    5  0  3 -5  4 -1
# 16:  B    6    7 -2  7  0  5  2
# 17:  B    7    5  2 -4 -5 -1 -3
# 18:  B    7    6  2 -7  0 -5 -2

这有点多余,因为它还显示了第3行-第1行(这只是负数)。如果不希望复制,请将row1 != row2更改为row1 < row2

代码语言:javascript
复制
df[, {  pairs <- CJ(row1 = 1:.N, row2 = 1:.N)[row1 < row2]
        data.table(pairs + .I[1] - 1, .SD[pairs[[1]]] - .SD[pairs[[2]]])
  }, by = t1]

#    t1 row1 row2 t2 t3 t4 t5 t6
# 1:  A    1    2  1  0 -1  7  1
# 2:  A    1    3  2  3  2  5  4
# 3:  A    1    4  1  2  4  7  2
# 4:  A    2    3  1  3  3 -2  3
# 5:  A    2    4  0  2  5  0  1
# 6:  A    3    4 -1 -1  2  2 -2
# 7:  B    5    6  0 -3  5 -4  1
# 8:  B    5    7 -2  4  5  1  3
# 9:  B    6    7 -2  7  0  5  2

解释:

CJ(a, b)为所有可能的值对(ai,bj)生成一行的data.table。示例:

代码语言:javascript
复制
CJ(1:3, 1:3)
#    V1 V2
# 1:  1  1
# 2:  1  2
# 3:  1  3
# 4:  2  1
# 5:  2  2
# 6:  2  3
# 7:  3  1
# 8:  3  2
# 9:  3  3

因为它是一个data.table,所以您可以通过在[]中使用非$前缀的列名进行子集,例如

代码语言:javascript
复制
CJ(a = 1:3, b = 1:3)[a < b]
#    a b
# 1: 1 2
# 2: 1 3
# 3: 2 3

j部分的dt[i, j, k]中,变量.SD是给定组的整个data.table子集(由k中的分组vars确定的组)。因此,这个答案接受每对元素的第一个元素,选择与这些元素.SD[pairs[[1]]]对应的组的行,并从中减去组中对应于每对.SD[pairs[[2]]]的其他元素的行。一个data.table是用pairs和这个减法的输出创建的。这是为每个组完成的,data.table会自动将所有组输出合并在一起。

票数 4
EN

Stack Overflow用户

发布于 2020-01-22 19:20:05

使用tidyverse,您可以在每个t1中使用笛卡尔连接。

代码语言:javascript
复制
dat %>% 
gather(key, value, -grp) %>% 
left_join(gather(dat, key, value, - grp), by = "grp") %>% 
mutate(diff = value.x - value.y)

  grp key.x value.x key.y value.y diff
1   A    t2       4    t2       4    0
2   A    t2       4    t2       3    1
3   A    t2       4    t2       2    2
4   A    t2       4    t2       3    1
5   A    t2       4    t3       6   -2
6   A    t2       4    t3       6   -2

注意,由于我的大脑并不总是遵守规则,所以我将t1重新命名为grp

票数 0
EN

Stack Overflow用户

发布于 2020-01-22 19:31:45

这是一个选择。我们将数据按组拆分,然后找到每个组的每一个行组合,然后映射出差异并重新连接。

代码语言:javascript
复制
library(tidyverse)


testDat %>%
  group_by(t1) %>%
  mutate(row = row_number()) %>%
  split(.$t1) %>%
  map(
    ~nest(., data = -c(t1, row)) %>%
      list(.,.) %>%
      reduce(full_join, by = "t1") %>%
      rename(row1 = row.x, row2 = row.y, vec1 = data.x, vec2 = data.y) %>%
      filter(row1 != row2) %>%
      mutate(diff = map2(vec1, vec2, ~unlist(.x)-unlist(.y)))%>%
      select(-vec1, -vec2) %>%
      unnest_wider(col = diff)
    ) %>%
  bind_rows()
#> # A tibble: 18 x 8
#> # Groups:   t1 [2]
#>    t1     row1  row2    t2    t3    t4    t5    t6
#>    <chr> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
#>  1 A         1     2     1     0    -1     7     1
#>  2 A         1     3     2     3     2     5     4
#>  3 A         1     4     1     2     4     7     2
#>  4 A         2     1    -1     0     1    -7    -1
#>  5 A         2     3     1     3     3    -2     3
#>  6 A         2     4     0     2     5     0     1
#>  7 A         3     1    -2    -3    -2    -5    -4
#>  8 A         3     2    -1    -3    -3     2    -3
#>  9 A         3     4    -1    -1     2     2    -2
#> 10 A         4     1    -1    -2    -4    -7    -2
#> 11 A         4     2     0    -2    -5     0    -1
#> 12 A         4     3     1     1    -2    -2     2
#> 13 B         1     2     0    -3     5    -4     1
#> 14 B         1     3    -2     4     5     1     3
#> 15 B         2     1     0     3    -5     4    -1
#> 16 B         2     3    -2     7     0     5     2
#> 17 B         3     1     2    -4    -5    -1    -3
#> 18 B         3     2     2    -7     0    -5    -2
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59866405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档