按列的子字符串聚合
Aggregating by a substring of column
考虑 R 中的以下数据框:
TYPE VARIAVEL VALOR
A OPER_RELAC_VARIAVEL1 100
A OPER_RELAC_VARIAVEL2 200
A OPER_RELAC_VARIAVEL3 300
B OPER_RELAC_VARIAVEL1 100
B OPER_RELAC_VARIAVEL2 200
B OPER_RELAC_VARIAVEL3 300
A CLI_RELAC_VARIAVEL1 450
A CLI_RELAC_VARIAVEL2 320
A CLI_RELAC_VARIAVEL3 110
我想根据 VARIAVEL
和 TYPE
的根获取每个 VALOR
的相关性。我没有包含 VARIAVEL
根的列,但它会在第二个 _
之前出现(本示例中的 OPER_RELAC
和 CLI_RELAC
)。
预期结果是:
TYPE VARIAVEL VALOR RELEVANCE
A OPER_RELAC_VARIAVEL1 100 0.167
A OPER_RELAC_VARIAVEL2 200 0.333
A OPER_RELAC_VARIAVEL3 300 0.500
B OPER_RELAC_VARIAVEL1 100 0.167
B OPER_RELAC_VARIAVEL2 200 0.333
B OPER_RELAC_VARIAVEL3 300 0.500
A CLI_RELAC_VARIAVEL1 450 0.511
A CLI_RELAC_VARIAVEL2 320 0.364
A CLI_RELAC_VARIAVEL3 110 0.125
因为,例如,450 代表类型 A
和根变量 CLI_RELAC
.
总数的 51.1%
我已经完成了这一系列命令:
1) 使用库stringr
生成一个带有根变量的列
dados$VARIAVEL_MAE <- str_match(dados$VARIAVEL, "^([^_]+[_][^_]+)")[,2]
感谢R:how to get grep to return the match, rather than the whole string
2) 在新的数据框中汇总由这个新列聚合的总数
TOTAIS <- aggregate(VALOR ~ Type + VARIAVEL_MAE, data = dados, sum)
names(TOTAIS) <- c('Type', 'VARIAVEL_MAE', 'TOTAL')
3) 使用建议 here
合并这两个数据帧
dados <- merge(TOTAIS, dados, by = c('Type', 'VARIAVEL_MAE'))
dados$RELEVANCIA <- dados$VALOR / dados$TOTAL;
是否有更聪明的方法,或者我确实需要所有这些步骤?
我的问题是因为在 R 中,我所做的一切总是可以被更快更小的东西所取代。
在 OP 的示例中,我们可以拆分 _
而不是使用正则表达式:
library(data.table)
setDT(DT)
DT[, paste0("vnome", 1:3) := tstrsplit(VARIAVEL, "_")]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vnome1, vnome2)]
TYPE VARIAVEL VALOR vnome1 vnome2 vnome3 z
1: A OPER_RELAC_VARIAVEL1 100 OPER RELAC VARIAVEL1 0.1666667
2: A OPER_RELAC_VARIAVEL2 200 OPER RELAC VARIAVEL2 0.3333333
3: A OPER_RELAC_VARIAVEL3 300 OPER RELAC VARIAVEL3 0.5000000
4: B OPER_RELAC_VARIAVEL1 100 OPER RELAC VARIAVEL1 0.1666667
5: B OPER_RELAC_VARIAVEL2 200 OPER RELAC VARIAVEL2 0.3333333
6: B OPER_RELAC_VARIAVEL3 300 OPER RELAC VARIAVEL3 0.5000000
7: A CLI_RELAC_VARIAVEL1 450 CLI RELAC VARIAVEL1 0.5113636
8: A CLI_RELAC_VARIAVEL2 320 CLI RELAC VARIAVEL2 0.3636364
9: A CLI_RELAC_VARIAVEL3 110 CLI RELAC VARIAVEL3 0.1250000
在更一般的情况下,OP 提到的 "everything before the second _
",我们可以使用另一个问答中的 (假设 VARIAVEL
不包含空格):
DT[, c("vroot", "vseq") :=
tstrsplit(sub('(^[^_]+_[^_]+)_(.*)$', '\1 \2', VARIAVEL), ' ')]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vroot)]
TYPE VARIAVEL VALOR vroot vseq z
1: A OPER_RELAC_VARIAVEL1 100 OPER_RELAC VARIAVEL1 0.1666667
2: A OPER_RELAC_VARIAVEL2 200 OPER_RELAC VARIAVEL2 0.3333333
3: A OPER_RELAC_VARIAVEL3 300 OPER_RELAC VARIAVEL3 0.5000000
4: B OPER_RELAC_VARIAVEL1 100 OPER_RELAC VARIAVEL1 0.1666667
5: B OPER_RELAC_VARIAVEL2 200 OPER_RELAC VARIAVEL2 0.3333333
6: B OPER_RELAC_VARIAVEL3 300 OPER_RELAC VARIAVEL3 0.5000000
7: A CLI_RELAC_VARIAVEL1 450 CLI_RELAC VARIAVEL1 0.5113636
8: A CLI_RELAC_VARIAVEL2 320 CLI_RELAC VARIAVEL2 0.3636364
9: A CLI_RELAC_VARIAVEL3 110 CLI_RELAC VARIAVEL3 0.1250000
数据:
DT = structure(list(TYPE = c("A", "A", "A", "B", "B", "B", "A", "A",
"A"), VARIAVEL = c("OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2",
"OPER_RELAC_VARIAVEL3", "OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2",
"OPER_RELAC_VARIAVEL3", "CLI_RELAC_VARIAVEL1", "CLI_RELAC_VARIAVEL2",
"CLI_RELAC_VARIAVEL3"), VALOR = c(100L, 200L, 300L, 100L, 200L,
300L, 450L, 320L, 110L)), .Names = c("TYPE", "VARIAVEL", "VALOR"
), row.names = c(NA, -9L), class = "data.frame")
考虑 R 中的以下数据框:
TYPE VARIAVEL VALOR
A OPER_RELAC_VARIAVEL1 100
A OPER_RELAC_VARIAVEL2 200
A OPER_RELAC_VARIAVEL3 300
B OPER_RELAC_VARIAVEL1 100
B OPER_RELAC_VARIAVEL2 200
B OPER_RELAC_VARIAVEL3 300
A CLI_RELAC_VARIAVEL1 450
A CLI_RELAC_VARIAVEL2 320
A CLI_RELAC_VARIAVEL3 110
我想根据 VARIAVEL
和 TYPE
的根获取每个 VALOR
的相关性。我没有包含 VARIAVEL
根的列,但它会在第二个 _
之前出现(本示例中的 OPER_RELAC
和 CLI_RELAC
)。
预期结果是:
TYPE VARIAVEL VALOR RELEVANCE
A OPER_RELAC_VARIAVEL1 100 0.167
A OPER_RELAC_VARIAVEL2 200 0.333
A OPER_RELAC_VARIAVEL3 300 0.500
B OPER_RELAC_VARIAVEL1 100 0.167
B OPER_RELAC_VARIAVEL2 200 0.333
B OPER_RELAC_VARIAVEL3 300 0.500
A CLI_RELAC_VARIAVEL1 450 0.511
A CLI_RELAC_VARIAVEL2 320 0.364
A CLI_RELAC_VARIAVEL3 110 0.125
因为,例如,450 代表类型 A
和根变量 CLI_RELAC
.
我已经完成了这一系列命令:
1) 使用库stringr
dados$VARIAVEL_MAE <- str_match(dados$VARIAVEL, "^([^_]+[_][^_]+)")[,2]
感谢R:how to get grep to return the match, rather than the whole string
2) 在新的数据框中汇总由这个新列聚合的总数
TOTAIS <- aggregate(VALOR ~ Type + VARIAVEL_MAE, data = dados, sum)
names(TOTAIS) <- c('Type', 'VARIAVEL_MAE', 'TOTAL')
3) 使用建议 here
合并这两个数据帧dados <- merge(TOTAIS, dados, by = c('Type', 'VARIAVEL_MAE'))
dados$RELEVANCIA <- dados$VALOR / dados$TOTAL;
是否有更聪明的方法,或者我确实需要所有这些步骤?
我的问题是因为在 R 中,我所做的一切总是可以被更快更小的东西所取代。
在 OP 的示例中,我们可以拆分 _
而不是使用正则表达式:
library(data.table)
setDT(DT)
DT[, paste0("vnome", 1:3) := tstrsplit(VARIAVEL, "_")]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vnome1, vnome2)]
TYPE VARIAVEL VALOR vnome1 vnome2 vnome3 z
1: A OPER_RELAC_VARIAVEL1 100 OPER RELAC VARIAVEL1 0.1666667
2: A OPER_RELAC_VARIAVEL2 200 OPER RELAC VARIAVEL2 0.3333333
3: A OPER_RELAC_VARIAVEL3 300 OPER RELAC VARIAVEL3 0.5000000
4: B OPER_RELAC_VARIAVEL1 100 OPER RELAC VARIAVEL1 0.1666667
5: B OPER_RELAC_VARIAVEL2 200 OPER RELAC VARIAVEL2 0.3333333
6: B OPER_RELAC_VARIAVEL3 300 OPER RELAC VARIAVEL3 0.5000000
7: A CLI_RELAC_VARIAVEL1 450 CLI RELAC VARIAVEL1 0.5113636
8: A CLI_RELAC_VARIAVEL2 320 CLI RELAC VARIAVEL2 0.3636364
9: A CLI_RELAC_VARIAVEL3 110 CLI RELAC VARIAVEL3 0.1250000
在更一般的情况下,OP 提到的 "everything before the second _
",我们可以使用另一个问答中的 VARIAVEL
不包含空格):
DT[, c("vroot", "vseq") :=
tstrsplit(sub('(^[^_]+_[^_]+)_(.*)$', '\1 \2', VARIAVEL), ' ')]
DT[, z := VALOR/sum(VALOR), by=.(TYPE, vroot)]
TYPE VARIAVEL VALOR vroot vseq z
1: A OPER_RELAC_VARIAVEL1 100 OPER_RELAC VARIAVEL1 0.1666667
2: A OPER_RELAC_VARIAVEL2 200 OPER_RELAC VARIAVEL2 0.3333333
3: A OPER_RELAC_VARIAVEL3 300 OPER_RELAC VARIAVEL3 0.5000000
4: B OPER_RELAC_VARIAVEL1 100 OPER_RELAC VARIAVEL1 0.1666667
5: B OPER_RELAC_VARIAVEL2 200 OPER_RELAC VARIAVEL2 0.3333333
6: B OPER_RELAC_VARIAVEL3 300 OPER_RELAC VARIAVEL3 0.5000000
7: A CLI_RELAC_VARIAVEL1 450 CLI_RELAC VARIAVEL1 0.5113636
8: A CLI_RELAC_VARIAVEL2 320 CLI_RELAC VARIAVEL2 0.3636364
9: A CLI_RELAC_VARIAVEL3 110 CLI_RELAC VARIAVEL3 0.1250000
数据:
DT = structure(list(TYPE = c("A", "A", "A", "B", "B", "B", "A", "A",
"A"), VARIAVEL = c("OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2",
"OPER_RELAC_VARIAVEL3", "OPER_RELAC_VARIAVEL1", "OPER_RELAC_VARIAVEL2",
"OPER_RELAC_VARIAVEL3", "CLI_RELAC_VARIAVEL1", "CLI_RELAC_VARIAVEL2",
"CLI_RELAC_VARIAVEL3"), VALOR = c(100L, 200L, 300L, 100L, 200L,
300L, 450L, 320L, 110L)), .Names = c("TYPE", "VARIAVEL", "VALOR"
), row.names = c(NA, -9L), class = "data.frame")