gpt4 book ai didi

r - 使用 colnames 中的模式划分列

转载 作者:行者123 更新时间:2023-12-02 06:46:35 26 4
gpt4 key购买 nike

假设我有以下简化表,其中分别包含动态列 a_x(其中 x 是索引,例如 0、1、2、3、4...)和 b_x。 a 列数始终等于 b 列数,但总列数可以是动态的(不总是 3 个 a 和3 b)。为了更清楚地说明以下示例描述了我的数据的结构:

> d <- read.table(text = "10 20 25 0.3 0.23 0.34 
40 20 30 0.25 0.4 0.45")
> names(d) <- c("a_0", "a_1", "a_2", "b_0", "b_1", "b_2")
> d
a_0 a_1 a_2 b_0 b_1 b_2
1 10 20 25 0.30 0.23 0.34
2 40 20 30 0.25 0.40 0.45

我想将 a 列与相应的 b 列分开,并将结果保存在新的 c 列中。为了进行除法,我使用 transform() 函数(带有硬编码的列名),如下所示:

transform(d, c_0 = as.numeric(as.character(a_0)) / as.numeric(as.character(b_0)))

考虑到输入数据的列数并不总是相同,我如何使用(可能)colnames 中的模式自动执行此步骤。

任何帮助将不胜感激

最佳答案

这里有几种方法。 (1) 和 (1a) 似乎最好,但其他确实显示了不同的方法。除了 (1a) 和 (2) 之外,它们的列名和顺序与问题中的列名和顺序相同,但如果这是一个问题,可以很容易地解决这些问题。除了 (4a) 之外,没有使用任何包。

1) 变换

ix <- grep("a", names(d))
cbind(d, setNames(d[ix] / d[-ix], sub("a", "c", names(d)[ix])))
## a_0 a_1 a_2 b_0 b_1 b_2 c_0 c_1 c_2
## 1 10 20 25 0.30 0.23 0.34 33.33333 86.95652 73.52941
## 2 40 20 30 0.25 0.40 0.45 160.00000 50.00000 66.66667

1a)这是 (1) 的变体;

transform(d, c = setNames(d[ix], ix-1) / d[-ix])  # ix is from above
## a_0 a_1 a_2 b_0 b_1 b_2 c.0 c.1 c.2
## 1 10 20 25 0.30 0.23 0.34 33.33333 86.95652 73.52941
## 2 40 20 30 0.25 0.40 0.45 160.00000 50.00000 66.66667

2) reshape 转换为长格式,执行除法并转换回宽格式。

varying <- split(names(d), sub("_.*", "", names(d)))
long <- reshape(d, dir = "long", varying = varying, v.names = names(varying))
reshape(transform(long, c = a / b), dir = "wide", idvar = "id")[-1]
## a.1 b.1 c.1 a.2 b.2 c.2 a.3 b.3 c.3
## 1.1 10 0.30 33.33333 20 0.23 86.95652 25 0.34 73.52941
## 2.1 40 0.25 160.00000 20 0.40 50.00000 30 0.45 66.66667

3) apply 我们可以转换为 3d 数组,然后使用 apply

nr <- nrow(d)
nc <- ncol(d)
cc <- apply(array(as.matrix(d), c(nr, nc / 2, 2)), 1:2, function(x) x[1] / x[2])
colnames(cc) <- paste("c", seq(0, length = ncol(cc)), sep = "_")
cbind(d, cc)
## a_0 a_1 a_2 b_0 b_1 b_2 c_0 c_1 c_2
## 1 10 20 25 0.30 0.23 0.34 33.33333 86.95652 73.52941
## 2 40 20 30 0.25 0.40 0.45 160.00000 50.00000 66.66667

4) diff 转置d的log,取diffs,通过exp转置反转log转置。然后将它绑定(bind)到 d。此解决方案假定所有条目都严格为正(问题中就是这种情况),以便我们可以记录日志。

nc <- ncol(d)
cc <- t(exp(-diff(t(log(d)), nc/2)))
colnames(cc) <- paste("c", seq(0, length = ncol(cc)), sep = "_")
cbind(d, cc)
## a_0 a_1 a_2 b_0 b_1 b_2 c_0 c_1 c_2
## 1 10 20 25 0.30 0.23 0.34 33.33333 86.95652 73.52941
## 2 40 20 30 0.25 0.40 0.45 160.00000 50.00000 66.66667

(4a) diff.zoo 支持执行除法而不是减法的几何差异。 (在当前版本的zoo diff.zoo 中要求输入的元素严格为正数,但在zoo 的开发版本中取消了此限制。)

library(zoo)

nc <- ncol(d)
cc <- 1 / t(diff(zoo(t(d)), nc/2, arith = FALSE))
colnames(cc) <- paste("c", seq(0, length = ncol(cc)), sep = "_")
cbind(d, cc)
## a_0 a_1 a_2 b_0 b_1 b_2 c_0 c_1 c_2
## x.1 10 20 25 0.30 0.23 0.34 33.33333 86.95652 73.52941
## x.2 40 20 30 0.25 0.40 0.45 160.00000 50.00000 66.66667

关于r - 使用 colnames 中的模式划分列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59861786/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com