对具有相似名称的列求和
Sum column with similar name
我在 R 中有一个像这样的数据集(我的真实数据集有更多的行和列):
AB1
AB3
AB4
XB1
XB3
XB4
12
34
0
5
3
7
我需要对类似的列求和
AB1+XB1 AB3+XB3 AB4+XB4
我可以使用什么代码?
试试这个:
library(tidyverse)
tribble(
~AB1, ~AB3, ~AB4, ~XB1, ~XB3, ~XB4,
12, 34, 0, 5, 3, 7
) |>
pivot_longer(everything(), names_pattern = "(\w\w)(\d)", names_to = c("prefix", "suffix")) |>
pivot_wider(names_from = prefix) |>
rowwise() |>
mutate(sum = sum(c_across(- suffix)))
#> # A tibble: 3 × 4
#> # Rowwise:
#> suffix AB XB sum
#> <chr> <dbl> <dbl> <dbl>
#> 1 1 12 5 17
#> 2 3 34 3 37
#> 3 4 0 7 7
由 reprex package (v2.0.1)
创建于 2022-05-11
假设是第一个变化的字符,其他的用来分组
df=read.table(text="
AB1 AB3 AB4 XB1 XB3 XB4
12 34 0 5 3 7
11 35 1 7 2 8",h=T)
sapply(
unique(substr(colnames(df),2,100)),
function(x){
rowSums(df[,grepl(x,colnames(df))])
}
)
B1 B3 B4
[1,] 17 37 7
[2,] 18 37 9
使用注释中的第 2 行 DF2 作为输入计算后缀 (s)、唯一后缀 (u) 并执行指定的矩阵乘法给出 (m)。最后将其转换回数据框并设置名称。没有使用包。
s <- substring(names(DF2), 2)
u <- unique(s)
m <- as.matrix(DF2) %*% outer(s, u, `==`)
sums <- setNames(as.data.frame(m), u); sums
## B1 B3 B4
## 1 17 37 7
## 2 17 37 7
如果需要将这些作为列附加到 DF2,则:
data.frame(DF2, sum = sums)
## AB1 AB3 AB4 XB1 XB3 XB4 sum.B1 sum.B3 sum.B4
## 1 12 34 0 5 3 7 17 37 7
## 2 12 34 0 5 3 7 17 37 7
备注
DF <- structure(list(AB1 = 12L, AB3 = 34L, AB4 = 0L, XB1 = 5L, XB3 = 3L,
XB4 = 7L), class = "data.frame", row.names = c(NA, -1L))
DF2 <- rbind(DF, DF)
DF2
## AB1 AB3 AB4 XB1 XB3 XB4
## 1 12 34 0 5 3 7
## 2 12 34 0 5 3 7
如果您知道结构是一致的(所有内容都是“A”和“X”对),那么这应该可行。
cols <- unique(substring(names(df), 2))
df[paste0("A", cols)] + df[paste0("X", cols)]
你可以使用
library(dplyr)
df %>%
mutate(across(starts_with("AB"),
~.x + df[[gsub("AB", "XB", cur_column())]],
.names = "sum_{.col}"))
这个returns
# A tibble: 1 x 9
AB1 AB3 AB4 XB1 XB3 XB4 sum_AB1 sum_AB3 sum_AB4
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 12 34 0 5 3 7 17 37 7
- 我们在此方法中使用
across
和 mutate
。
- 首先我们 select 所有以
AB
开头的列。所需的总和始终为 ABn + XB2
,因此我们可以使用此模式。
- 接下来,我们将当前 selected 列名称中的
AB
替换为 XB
并将这两列相加。这些总和存储在以 sum_
. 为前缀的新列中
我们可以试试下面的代码
cbind(
df,
list2DF(lapply(
split.default(df, gsub("\D+", "", names(df))),
rowSums
))
)
这给出了
AB1 AB3 AB4 XB1 XB3 XB4 1 3 4
1 12 34 0 5 3 7 17 37 7
across2
来自 dplyover
的选项
library(dplyover)
df1 %>%
mutate(across2(starts_with('AB'), starts_with('XB'),
~ .x + .y, .names = "sum_{xcol}"))
AB1 AB3 AB4 XB1 XB3 XB4 sum_AB1 sum_AB3 sum_AB4
1 12 34 0 5 3 7 17 37 7
我在 R 中有一个像这样的数据集(我的真实数据集有更多的行和列):
AB1 | AB3 | AB4 | XB1 | XB3 | XB4 |
---|---|---|---|---|---|
12 | 34 | 0 | 5 | 3 | 7 |
我需要对类似的列求和
AB1+XB1 AB3+XB3 AB4+XB4
我可以使用什么代码?
试试这个:
library(tidyverse)
tribble(
~AB1, ~AB3, ~AB4, ~XB1, ~XB3, ~XB4,
12, 34, 0, 5, 3, 7
) |>
pivot_longer(everything(), names_pattern = "(\w\w)(\d)", names_to = c("prefix", "suffix")) |>
pivot_wider(names_from = prefix) |>
rowwise() |>
mutate(sum = sum(c_across(- suffix)))
#> # A tibble: 3 × 4
#> # Rowwise:
#> suffix AB XB sum
#> <chr> <dbl> <dbl> <dbl>
#> 1 1 12 5 17
#> 2 3 34 3 37
#> 3 4 0 7 7
由 reprex package (v2.0.1)
创建于 2022-05-11假设是第一个变化的字符,其他的用来分组
df=read.table(text="
AB1 AB3 AB4 XB1 XB3 XB4
12 34 0 5 3 7
11 35 1 7 2 8",h=T)
sapply(
unique(substr(colnames(df),2,100)),
function(x){
rowSums(df[,grepl(x,colnames(df))])
}
)
B1 B3 B4
[1,] 17 37 7
[2,] 18 37 9
使用注释中的第 2 行 DF2 作为输入计算后缀 (s)、唯一后缀 (u) 并执行指定的矩阵乘法给出 (m)。最后将其转换回数据框并设置名称。没有使用包。
s <- substring(names(DF2), 2)
u <- unique(s)
m <- as.matrix(DF2) %*% outer(s, u, `==`)
sums <- setNames(as.data.frame(m), u); sums
## B1 B3 B4
## 1 17 37 7
## 2 17 37 7
如果需要将这些作为列附加到 DF2,则:
data.frame(DF2, sum = sums)
## AB1 AB3 AB4 XB1 XB3 XB4 sum.B1 sum.B3 sum.B4
## 1 12 34 0 5 3 7 17 37 7
## 2 12 34 0 5 3 7 17 37 7
备注
DF <- structure(list(AB1 = 12L, AB3 = 34L, AB4 = 0L, XB1 = 5L, XB3 = 3L,
XB4 = 7L), class = "data.frame", row.names = c(NA, -1L))
DF2 <- rbind(DF, DF)
DF2
## AB1 AB3 AB4 XB1 XB3 XB4
## 1 12 34 0 5 3 7
## 2 12 34 0 5 3 7
如果您知道结构是一致的(所有内容都是“A”和“X”对),那么这应该可行。
cols <- unique(substring(names(df), 2))
df[paste0("A", cols)] + df[paste0("X", cols)]
你可以使用
library(dplyr)
df %>%
mutate(across(starts_with("AB"),
~.x + df[[gsub("AB", "XB", cur_column())]],
.names = "sum_{.col}"))
这个returns
# A tibble: 1 x 9
AB1 AB3 AB4 XB1 XB3 XB4 sum_AB1 sum_AB3 sum_AB4
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 12 34 0 5 3 7 17 37 7
- 我们在此方法中使用
across
和mutate
。 - 首先我们 select 所有以
AB
开头的列。所需的总和始终为ABn + XB2
,因此我们可以使用此模式。 - 接下来,我们将当前 selected 列名称中的
AB
替换为XB
并将这两列相加。这些总和存储在以sum_
. 为前缀的新列中
我们可以试试下面的代码
cbind(
df,
list2DF(lapply(
split.default(df, gsub("\D+", "", names(df))),
rowSums
))
)
这给出了
AB1 AB3 AB4 XB1 XB3 XB4 1 3 4
1 12 34 0 5 3 7 17 37 7
across2
来自 dplyover
library(dplyover)
df1 %>%
mutate(across2(starts_with('AB'), starts_with('XB'),
~ .x + .y, .names = "sum_{xcol}"))
AB1 AB3 AB4 XB1 XB3 XB4 sum_AB1 sum_AB3 sum_AB4
1 12 34 0 5 3 7 17 37 7