2

我在 R 中有下表。我有 2 个 A 列、3 个 B 列和 1 个 C 列。我需要计算任何同名列之间可能存在的最大差异,并将列名作为输出返回。

对于第 1 行

  • A 之间的最大差值为 2
  • B之间的最大差异是4
  • 我需要输出为 B

对于第 2 行

  • A之间的最大差异是3
  • B 之间的最大差值为 2
  • 我需要输出为 A
| A  | A | B | B | B | C |
| 2  | 4 |5  |2  |1  |0  |
| -3 |0  |2  |3  |4  |2  |
4

3 回答 3

2

首先,使用非唯一的列名有点危险(在某些情况下是不允许的),所以我做的第一件事是使用base::make.unique(). 从那里,我使用tidyr::pivot_longer()以便可以更轻松地访问包含在列名中的分组信息。在这里,我使用内部的正则表达式names_pattern来丢弃列名的不同部分,以便它们再次相同。然后我们使用dplyr::group_by()其次dplyr::summarize()来获得最大的差异,idgrp对应于原始数据中的行和相似列。最后,我们使用dplyr::slice_max()只返回每组的最大差异。

library(tidyverse)

d <- structure(list(A = c(2L, -3L), A = c(4L, 0L), B = c(5L, 2L), B = 2:3, B = c(1L, 4L), C = c(0L, 2L)), row.names = c(NA, -2L), class = "data.frame")

# give unique names
names(d) <- make.unique(names(d), sep = "_")

d %>% 
  mutate(id = row_number()) %>% 
  pivot_longer(-id, names_to = "grp", names_pattern = "([A-Z])*") %>% 
  group_by(id, grp) %>% 
  summarise(max_diff = max(value) - min(value)) %>% 
  slice_max(order_by = max_diff, n = 1, with_ties = F)

#> `summarise()` has grouped output by 'id'. You can override using the `.groups` argument.
#> # A tibble: 2 x 3
#> # Groups:   id [2]
#>      id grp   max_diff
#>   <int> <chr>    <int>
#> 1     1 B            4
#> 2     2 A            3

reprex 包于 2022-02-14 创建(v2.0.1)

于 2022-02-14T02:14:25.630 回答
1

aggregate这是使用+ range+ diff+的基本 R 选项which.max

df$max_diff <- with(
  p <- aggregate(
    . ~ id,
    cbind(id = names(df), as.data.frame(t(df))),
    function(v) diff(range(v))
  ),
  id[sapply(p[-1],which.max)]
)

这使

> df
   A A B B B C max_diff
1  2 4 5 2 1 0        B
2 -3 0 2 3 4 2        A

数据

> dput(df)
structure(list(A = c(2L, -3L), A = c(4L, 0L), B = c(5L, 2L), 
    B = 2:3, B = c(1L, 4L), C = c(0L, 2L), max_diff = c("B",
    "A")), row.names = c(NA, -2L), class = "data.frame")
于 2022-02-14T09:03:04.940 回答
1

我们也可以split.default根据列名的相似性进行拆分,然后max.col找到max差异的索引

m1 <- sapply(split.default(df, names(df)), \(x)
    apply(x, 1, \(u) diff(range(u))))
df$max_diff <- colnames(m1)[max.col(m1, "first")]
df$max_diff
[1] "B" "A"
于 2022-02-14T16:34:14.507 回答