一次操作多列(或行)的编程方式是什么?考虑一下这个例子:
df2 <- data.frame(a = 1:10, b = 5:14, c = 10:1, d = 14:5)
我想创建两个包含a / b和c / d比率的新列。为简单起见,我们假设所有列之间的空间关系是一致的。只需要制作两列,就可以这样做:
df2$ab <- with(df2, a/b)
df2$cd <- with(df2, c/d)
或
df2 <- transform(df2, ab = a/b, cd = c/d)
创建最终产品,如:
a b c d ab cd
1 1 5 10 14 0.2000000 0.7142857
2 2 6 9 13 0.3333333 0.6923077
3 3 7 8 12 0.4285714 0.6666667
4 4 8 7 11 0.5000000 0.6363636
5 5 9 6 10 0.5555556 0.6000000
6 6 10 5 9 0.6000000 0.5555556
7 7 11 4 8 0.6363636 0.5000000
8 8 12 3 7 0.6666667 0.4285714
9 9 13 2 6 0.6923077 0.3333333
10 10 14 1 5 0.7142857 0.2000000
但是,如果有100个列需要迭代怎么办?我通常使用Excel或SQL来连接代码并将其放在我的.R脚本中,但似乎必须有办法用R来解决这个问题。
完全披露:此问题与cross validated上的一个问题有关,我在这个问题上将一个无法解决的解决方案整合在一起。
答案 0 :(得分:4)
试试这个解决方案:
df2 <- data.frame(a = 1:10, b = 5:14, c = 10:1, d = 14:5, e = 34:43, f = 56:65)
n <- ncol(df2)
s1 <- seq(1, n, 2)
s2 <- seq(2, n, 2)
df2[paste(names(df2)[s1], names(df2)[s2], sep="")] <- df2[, s1] / df2[, s2]
答案 1 :(得分:0)
这个解决方案怎么样?它避免了多次cbind
对象自身:
for (i in seq(1, ncol(df2), by = 2)) {
df2[, paste(names(df2)[i], names(df2)[i+1], sep = "", collapse = "")] <- df2[, i] / df2[, i + 1]
}
编辑:看起来我的解决方案比@ djhurio的
略快> set.seed(42)
> df2 <- data.frame(
+ a = sample(1:10, 10e6, T)
+ , b = sample(1:10, 10e6, T)
+ , c = sample(1:10, 10e6, T)
+ , d = sample(1:10, 10e6, T)
+ )
>
> system.time(
+ for (i in seq(1, ncol(df2), by = 2)) {
+ df2[, paste(names(df2)[i], names(df2)[i+1], sep = "", collapse = "")] <- df2[, i] / df2[, i + 1]
+ }
+ )
user system elapsed
1.06 0.64 1.70
>
> foo <- function(df2) {
+ n <- ncol(df2)
+ s1 <- seq(1, n, 2)
+ s2 <- seq(2, n, 2)
+ df2 <- cbind(df2, df2[, s1] / df2[, s2])
+ names(df2)[(n+1):ncol(df2)] <- paste(names(df2)[s1], names(df2)[s2], sep="")
+ return(df2)
+ }
>
> set.seed(42)
> df2 <- data.frame(
+ a = sample(1:10, 10e6, T)
+ , b = sample(1:10, 10e6, T)
+ , c = sample(1:10, 10e6, T)
+ , d = sample(1:10, 10e6, T)
+ )
> system.time(foo(df2))
user system elapsed
1.73 0.85 2.57