在R中使用函数而不是循环:以异常的方式反复减去以前的行 [英] Use function instead of for loop in R: substracting previous rows iteratively with exceptions

查看:140
本文介绍了在R中使用函数而不是循环:以异常的方式反复减去以前的行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个很大的数据集,我希望每行的值减去下一行,除了第五行。使用for循环,它非常简单,但对于我的大数据集,它需要一个多小时。我已经被告知,使用函数的速度要快得多,但我不知道如何编写复杂的函数,而且我也找不到类似问题的例子。



< pre $ #set up matrix
x = matrix(0,15,2)
x [,1] = c(1,5,4,3,4,2 (0:((nrow(x)/ 4,3,7,8,3,2,9,7,3)

#run for循环
5)-1)* 5)){
x [i + 1,2] <-x [i + 1,1] -x [i + 2,1]
x [i + 2, 2] <-x [i + 2,1] -x [i + 3,1]
x [i + 3,2] <-x [i + 3,1] -x [i + 4 ,1]
x [i + 4,2] <-x [i + 4,1] -x [i + 5,1]
x [i + 5,2] <-x [ i + 5,1]
}

甚至没有按照我认为的方式工作......

  apply(x,FUN = function(i)x [ i] -x [i + 1],MARGIN = 1)

编辑:我想出了如何使for循环不同,使用if ... else ...语句在我的for循环中,这可能是写入函数的一步。

  for(i in 1:nrow(x)){
if(i %% 5 == 0){#thos e行是
x [i,2]< -x [i,1]
}的倍数的其他行{#对于所有其他行
x [i,2]< x [i,1] -x [i + 1,1]
}
}


解决方案

您可以使用矢量化计算完成此操作。如果您使用 nrow(x)而不是 15 ,则这会扩大规模。

 #为5,10,... 
index.fifth设置索引< -seq(5, 15,5)
#为1:4,6:9,11:14设置索引,...
#基本上删除每个第五个索引的索引
index.rest< - seq(1:15)[ - index.fifth]
#首先计算减法
x [index.rest,2]< -x [index.rest,1] -x [index.rest + 1 ,1]
#将5,10 ......设置为它们的值
x [index.fifth,2]< -x [index.fifth,1]


I have a large dataset for which I want to get the value of each row minus the following row except for each fifth row. With a for loop, it is fairly simple but with my large dataset, it takes over an hour. I've been told that apply with a function is MUCH faster, but I don't know how to write a complicated function and I can't find examples of similar problems.

#set up matrix
x=matrix(0,15,2)
x[,1]=c(1, 5, 4, 3, 4, 2, 4, 3, 7, 8, 3, 2, 9, 7, 3)

#run for loop
for (i in c(0:((nrow(x)/5)-1)*5)){ 
x[i+1,2]<-x[i+1,1]-x[i+2,1]
x[i+2,2]<-x[i+2,1]-x[i+3,1]
x[i+3,2]<-x[i+3,1]-x[i+4,1]
x[i+4,2]<-x[i+4,1]-x[i+5,1]
x[i+5,2]<-x[i+5,1]
     }

I got as far as this using apply but it doesn't even work the way I thought it would...

apply(x, FUN=function(i) x[i]-x[i+1], MARGIN=1)

EDIT: I figured out how to make the for loop different using if ... else... statement within my for loop which might be one step in writing the function.

for (i in 1:nrow(x)){ 
if (i%%5==0){# for those rows that are a multiple of five
    x[i,2]<-x[i,1]
}else{ # for all other rows
    x[i,2]<-x[i,1]-x[i+1,1]
}
}

解决方案

You can do this with a vectorized calculation. This scales up if you use nrow(x) instead of 15.

# set up indexes for the 5, 10, ...
index.fifth<-seq(5,15,5)
# set up indexes for 1:4,6:9,11:14,...
# basically delete the ones for every fifth one
index.rest<-seq(1:15)[-index.fifth]
# calculate subtractions first
x[index.rest,2]<-x[index.rest,1]-x[index.rest+1,1]
# set 5, 10, ... to their values
x[index.fifth,2]<-x[index.fifth,1]

这篇关于在R中使用函数而不是循环:以异常的方式反复减去以前的行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆