在R中是否存在类似构造的“收益”?

时间:2011-10-23 11:40:18

标签: arrays r for-loop

我是R的新手,刚开始使用它绘制一些图表。

我有这段代码:

times=integer(nrow(df));
for(i in 1:nrow(df)) {
  time=df[i+1,4]-df[i,4];
  times[i]<-time
}

必须有一个更聪明的方法来做到这一点,没有先初始化时间,不是吗? 我不确定,但我正在寻找的是:

times <- for(i in 1:nrow(df)) yield df[i+1,4]-df[i,4]

(我知道这不是有效代码:)) 我希望这个问题不会被问到。我搜索并没有找到任何关于“yield”和数组初始化的具体内容。

根据要求....

df中的示例数据:

7926 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7927 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7928 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7929 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7930 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7931 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7932 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7933 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7934 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7935 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7936 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7937 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12
7938 08:00:27:ed:f3:e5 MESSAGEHANDLER START 1.319242e+12
7939 08:00:27:ed:f3:e5 MESSAGEHANDLER   END 1.319242e+12

我的循环之后是时间:

[7921] 508 500 497 501 466 502 505 500 488 501 500 501 490 501 478 501 501 501
[7939]  NA

好的,为了更具体,我真正想做的是:

times1=integer(nrow(df));for(i in 1:nrow(df)) { if (df[i,3] == "START") times1[i]<-df[i+1,4]-df[i,4]}
times2=integer(nrow(df));for(i in 1:nrow(df)) { if (df[i,3] == "END") times2[i]<-df[i+1,4]-df[i,4]}

然后输出类似于times1:

[7921]   0 500   0 501   0 502   0 500   0 501   0 501   0 501   0 501   0 501
[7939]   0

但我需要:

[3960]   500   501   502   500   501   501   501   501   501

用语言说:

我正在解析来自csv文件的测量数据,如上所述,该文件以df登陆。 这是“START”后跟“END”

df中的数据描述了当df [,4]中的df [,3]中的“START”在df [,4]中的特定单位时间内以毫秒为单位时接收到数据包。 现在我需要计算从接收到发送的时间(这是时间,我的机器需要分析RECEIVED PACKET并计算结果以发送它。) 所以在df [,3]中的END意味着数据包在unixtime df [,4]成功发送。

另一种情况是“结束”,然后是“开始”

这是在“我的信息包已发送”和新信息“收到”之间传递的时间。

我现在添加一个csv样本和我的完整代码以供复制:

#load csv in df!
df = read.csv("/tmp/measure.csv",FALSE)
absolute=integer(nrow(df));for(i in 1:nrow(df)) {time=df[i,4]-df[1,4];absolute[i]<-(time/1000)}
times=integer(nrow(df));for(i in 1:nrow(df)) {time=df[i+1,4]-df[i,4];times[i]<-time}
#plot(absolute,times)
plot(absolute,times,lty=1,pch=1,col="#11223399",type="l")
lines(absolute,array(mean(times,na.rm=1),nrow(df)),col="red")

这里是我的measure.csv:

08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238175202
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238175690
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238176195
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238176665
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238177167
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238177669
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238178172
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238178639
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238179139
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238179658
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238180161
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238180654
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238181154
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238181669
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238182170
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,START,1319238182629
08:00:27:ed:f3:e5,TMCMESSAGEHANDLER,END,1319238183130

我希望这更清楚。

4 个答案:

答案 0 :(得分:4)

我认为你想要计算向量中连续元素之间的差异。在这种情况下,您正在寻找diff

set.seed(0)
x <- sample(1:10, 5)

x
[1] 1 2 9 5 3

diff(x)
[1]  1  7 -4 -2

答案 1 :(得分:3)

希望我不会太离谱 - 为什么不完全避免循环?:

    # generate some data sort of similar to yours:
    DF <- data.frame(pos4 = rep(c("START","END"),10),times=rep(0,20))
    DF$times[DF$pos4=="START"] <- 1:10
    DF$times[DF$pos4=="END"] <- DF$times[DF$pos4=="START"]+runif(10)
    DF
    DF
        pos4 times
    1  START  1.000000
    2    END  1.750459
    3  START  2.000000
    4    END  2.212599
    5  START  3.000000
    6    END  3.974809
    ....

我假设您的数据集中的START和END时间是有序的..

    (times <- DF$times[DF$pos4=="END"] - DF$times[DF$pos4=="START"]) 
    [1] 0.7504590 0.2125986 0.9748094 0.3313644 0.3448410 0.8677022 0.9534317
    [8] 0.1279304 0.6500212 0.1798664

不确定您需要做什么样的检查,因为它们不在您在问题中发布的for循环中。

----------------- EDIT ---------------------------

从下面的评论中包含似乎已经正确的评论, 这真的是一个关于索引的问题: 其中:

    DIFFS <- diff(DF$times)

给你所有的差异,你只想把它分成两个对象,一个用于偶数索引,另一个用于奇数索引:

    times1 <- DIFFS[seq(from=1,to=length(DIFFS),by=2)]
    times2 <- DIFFS[seq(from=2,to=length(DIFFS),by=2)]

并且不相关,但也很有用:你在代码中对象的名称使用了'absolute'和'df',但这些也是R中的函数,所以尽管它有效,但是给它们起名字的形式更好已经采取了。很高兴你得到了你想要的东西!

答案 2 :(得分:2)

您也可以执行类似

的操作
lapply(sequence(nrow(df)-1),function(i,df) df[i+1,4]-df[i,4],df)

或尝试sapply代替lapply(否则,语法相同)。

编辑:

更具体地说,我认为

times <- sapply(sequence(nrow(df)-1),function(i,df) df[i+1,4]-df[i,4],df)

times <- unlist(lapply(sequence(nrow(df)-1),function(i,df) df[i+1,4]-df[i,4],df))

会做到这一点。关于重塑,df中没有将开始和结束时间配对在一起的标识变量,因此必须手动进行,假设要配对的两个在连续的行中出现:

times <- apply(matrix(df[,4],ncol=2,byrow=TRUE),1,diff)

答案 3 :(得分:0)

我正在出门,但有两条评论:1)向数据框添加列标题2)我认为OP需要重塑包将其开始结束时间分成2个不同的列,分别称为start和then end 。然后在向量上使用End-Start操作。