【问题标题】:R: summation of rows in a data frameR:数据框中行的总和
【发布时间】:2015-03-16 17:33:31
【问题描述】:

我想要做什么:我有一个数据框,其中第一列由字符串组成,其余列用数值填充。我想将前三行以三组的形式添加到其余行中,同时对行应用不同的因素,例如:row1*x + row4*y, row1*x + row5*y, row1*x + row6* y,然后 row2*x+row4*y,依此类推,直到 row3*x+row6*y。然后我想再次做同样的事情,但 x 和 y 使用不同的值,然后第三次使用不同的 x 和 y 值。然后我想对第 1-3 行和第 7-9 行做同样的事情,然后对 1-3 和 10-12 做同样的事情。确切的顺序很重要。我想将所有这些写成新数据框中的行。

我还想组合第一列的各个字符串,添加一个标记以便我知道我做了哪个总和,然后每组一个连续的计数器。我想将它添加到我的结果数据框中,这样我就可以看到哪一行来自哪里。

我所拥有的:在大量使用 for 循环之后,这段代码最终完全符合我的要求,但它很难看,而且我的实际数据非常慢(实际数据框有 1762 列)。

numbers <- data.frame(replicate(10,sample(1:100,12,rep=TRUE))) 
id <- data.frame(id=c("d1","d2","d3","v11","v12","v13","v21","v22","v23","v31","v32","v33"))
data <- cbind(id,numbers)

results <- data.frame() 
data.raw <- data[,-1] 
legend <- data.frame()
q=1 
#################### rows 1-3 with rows 4-6
k=1 # my continuous counter
for(i in 1:3) {
    for(j in 4:6){
        results <- rbind(results,0.99*(data.raw[i,])+0.01*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"01",k,sep="_")
        q=q+1
        k=k+1 }}
k=1
for(i in 1:3){
    for(j in 4:6){  
        results <- rbind(results,0.95*(data.raw[i,])+0.05*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"05",k,sep="_")
    q=q+1
    k=k+1 }}
k=1
for(i in (1:3)){
    for(j in 4:6){  
        results <- rbind(results,0.9*(data.raw[i,])+0.1*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"10",k,sep="_")
        q=q+1 
        k=k+1   }}
#################### rows 1-3 with rows 7-9
k=1
for(i in 1:3){
    for(j in 7:9){
        results <- rbind(results,0.99*(data.raw[i,])+0.01*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"01",k,sep="_")
        q=q+1
        k=k+1 }}
k=1
for(i in 1:3){
    for(j in 7:9){  
        results <- rbind(results,0.95*(data.raw[i,])+0.05*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"05",k,sep="_")
        q=q+1
        k=k+1 }}
k=1
for(i in 1:3){
    for(j in 7:9){  
        results <- rbind(results,0.9*(data.raw[i,])+0.1*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"10",k,sep="_")
        q=q+1 
        k=k+1   }}
#################### rows 1-3 with rows 10-12
k=1
for(i in 1:3){
    for(j in 10:12){
        results <- rbind(results,0.99*(data.raw[i,])+0.01*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"01",k,sep="_")
        q=q+1
        k=k+1 }}
k=1
for(i in 1:3){
    for(j in 10:12){    
        results <- rbind(results,0.95*(data.raw[i,])+0.05*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"05",k,sep="_")
        q=q+1
        k=k+1 }}
k=1
for(i in 1:3){
    for(j in 10:12){    
        results <- rbind(results,0.9*(data.raw[i,])+0.1*(data.raw[j,]))
        legend[q,1] <- paste(data[i,1],data[j,1],"10",k,sep="_")
        q=q+1 
        k=k+1   }}

mydataframe <- cbind(legend,results)

我想要的是:更漂亮、更短、更快的东西。显然可以用函数替换 for 循环,但这就是我迷路的地方。我想我可以使用apply 系列中的一些东西,但我还不完全理解函数的概念,然后使用描述性字符串变得更加复杂。

有人可以指点我正确的方向吗?

【问题讨论】:

    标签: r for-loop


    【解决方案1】:

    第一步,不要使用数据框,而是将它们转换为矩阵。简单地改变

    results <- data.frame() 
    data.raw <- data[,-1] 
    

    results<-c()
    data.raw <- as.matrix(data[,-1] )
    

    在顶部应该会加快速度。

    【讨论】:

    • results&lt;-c() 真的有帮助吗?也就是说,您仍然需要 grow 对象,这是昂贵的操作。相反,您可以使用?vector 将其初始化为所需的大小(如果从一开始就没有明确定义,则大致为大小)。
    • 有点帮助。我得到 318ms 的原始代码,43ms 的更改 data.raw 和 17ms 更改两者。将结果初始化为正确的大小可能会使其更快。我不知道 R 是否足够聪明,可以发现 results 正在被每个 rbind 替换,所以它实际上可以在线性摊销时间内完成整个事情。
    • 谢谢!这真的很有帮助,代码现在超级快!谁想到会这么容易。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多