在R中查找同名列之间的最大差异
Finding maximum difference between columns of same name in R
我在 R 中有以下 table。我有 2 个 A 列、3 个 B 列和 1 个 C 列。我需要计算任何同名列和 return 作为输出的列名之间可能存在的最大差异。
第 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 |
首先,使用 non-unique 列名有点危险(在某些情况下是不允许的),所以我做的第一件事是使用 base::make.unique()
来唯一化名称。从那里开始,我使用 tidyr::pivot_longer()
以便可以更轻松地访问列名称中包含的分组信息。在这里,我在 names_pattern
中使用正则表达式来丢弃列名的不同部分,以便它们再次相同。然后我们使用 dplyr::group_by()
后跟 dplyr::summarize()
来获得每个 id
和 grp
的最大差异,它们对应于原始数据中的行和类似列。最后我们使用 dplyr::slice_max()
到 return 只有每组最大的差异。
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 package (v2.0.1)
于 2022-02-14 创建
这里是基础 R 选项,使用 aggregate
+ range
+ diff
+ 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")
我们也可以使用split.default
根据列名相似度进行拆分,然后用max.col
找到max
diff
的索引
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"
我在 R 中有以下 table。我有 2 个 A 列、3 个 B 列和 1 个 C 列。我需要计算任何同名列和 return 作为输出的列名之间可能存在的最大差异。
第 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 |
首先,使用 non-unique 列名有点危险(在某些情况下是不允许的),所以我做的第一件事是使用 base::make.unique()
来唯一化名称。从那里开始,我使用 tidyr::pivot_longer()
以便可以更轻松地访问列名称中包含的分组信息。在这里,我在 names_pattern
中使用正则表达式来丢弃列名的不同部分,以便它们再次相同。然后我们使用 dplyr::group_by()
后跟 dplyr::summarize()
来获得每个 id
和 grp
的最大差异,它们对应于原始数据中的行和类似列。最后我们使用 dplyr::slice_max()
到 return 只有每组最大的差异。
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 package (v2.0.1)
于 2022-02-14 创建这里是基础 R 选项,使用 aggregate
+ range
+ diff
+ 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")
我们也可以使用split.default
根据列名相似度进行拆分,然后用max.col
找到max
diff
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"