Есть ли в R конструкция, похожая на «доходность»? - PullRequest
0 голосов
/ 23 октября 2011

Я немного новичок в 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, как показано выше. Это для «СТАРТ», за которым следует «КОНЕЦ»

Данные в df описывают, что пакет был получен при наличии «START» в df [, 3] в определенное время unix в миллисекундах в df [, 4]. Теперь мне нужно рассчитать время, прошедшее с момента получения до отправки (это время, когда моей машине нужно проанализировать ПОЛУЧЕННЫЙ ПАКЕТ и вычислить результат, чтобы ОТПРАВИТЬ его). Таким образом, END в df [, 3] означает, что пакет был успешно отправлен в unixtime df [, 4].

Другой случай - «END», за которым следует «START»

Это время, которое прошло между «мой пакет был отправлен» и новый «был получен».

Теперь я добавляю образец 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")

Вот мой показатель .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 ]

4 голосов
/ 23 октября 2011

Я думаю, что вы хотите вычислить разницу между последовательными элементами в векторе. В этом случае вы ищете diff:

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

x
[1] 1 2 9 5 3

diff(x)
[1]  1  7 -4 -2
3 голосов
/ 23 октября 2011

Надеюсь, я не слишком далеко - почему бы вообще не избежать цикла?:

    # 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, который вы опубликовали в вопросе.

----------------- РЕДАКТИРОВАТЬ ---------------------------

, чтобы включить из комментария ниже, который, кажется, имеетправильно понял, это действительно был вопрос об индексации: где:

    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 голосов
/ 23 октября 2011

Вы также можете сделать что-то вроде

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)
0 голосов
/ 23 октября 2011

Я ухожу за дверь, но 2 комментария: 1) добавить заголовки столбцов к фрейму данных 2) я думаю, что OP нужен пакет изменения формы, чтобы разделить его время окончания начала на 2 разных столбца, называемых start и затем end , затем используйте операцию End-Start для вектора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...