3

我是 R 的初学者。我发现所有这些奇妙的功能都可以分析数据。我想通过检测事件变化来过滤数据框。例如,如果我们采用以下数据:

testcase                date  event
1  TESTCASE1 2013-06-12 18:12:09 EVENT1
2  TESTCASE1 2013-06-12 18:12:12 EVENT1
3  TESTCASE1 2013-06-12 18:12:15 EVENT2
4  TESTCASE1 2013-06-12 18:12:16 EVENT2
5  TESTCASE1 2013-06-12 18:12:25 EVENT1
6  TESTCASE2 2013-06-12 18:12:10 EVENT4
7  TESTCASE2 2013-06-12 18:12:16 EVENT4
8  TESTCASE2 2013-06-12 18:12:17 EVENT2
9  TESTCASE2 2013-06-12 18:12:26 EVENT2
10 TESTCASE2 2013-06-12 18:12:30 EVENT1

我只想返回发生事件更改的行。对于这个例子,它给出了这个:

    testcase                date  event
2  TESTCASE1 2013-06-12 18:12:12 EVENT1
3  TESTCASE1 2013-06-12 18:12:15 EVENT2
4  TESTCASE1 2013-06-12 18:12:16 EVENT2
5  TESTCASE1 2013-06-12 18:12:25 EVENT1
7  TESTCASE2 2013-06-12 18:12:16 EVENT4
8  TESTCASE2 2013-06-12 18:12:17 EVENT2
9  TESTCASE2 2013-06-12 18:12:26 EVENT2
10 TESTCASE2 2013-06-12 18:12:30 EVENT1

我发现这样做的唯一方法是使用循环。它给出以下代码:

result <- data.frame(   testcase = 

c("TESTCASE1","TESTCASE1","TESTCASE1","TESTCASE1","TESTCASE1","TESTCASE2","TESTCASE2","TESTCASE2","TESTCASE2","TESTCASE2"),
            date = c("2013-06-12 18:12:09","2013-06-12 18:12:12","2013-06-12 18:12:15","2013-06-12 18:12:16","2013-06-12 18:12:25","2013-06-12 18:12:10","2013-06-12 18:12:16","2013-06-12 18:12:17","2013-06-12 18:12:26","2013-06-12 18:12:30"),
            event = c("EVENT1","EVENT1","EVENT2","EVENT2","EVENT1","EVENT4","EVENT4","EVENT2","EVENT2", "EVENT1"))

tc <- result[1,"testcase"]

currentDate <- result[1,"date"]
currentEvent <- result[1,"event"]
#index variable de sortieoutput
j <- 1
output <- c()

for(i in 2:length(result[,1])){
    if(tc != result[i,"testcase"]){
        tc <- result[i,"testcase"];
        currentEvent <- result[i,"event"]
    }else{
        #detection de handhover
        if(result[i,"event"] != currentEvent){
            output[j] <- i-1
            output[j+1] <- i
            j <- j+2
            currentEvent <- result[i,"event"]
        }
    }
}

output_data <- result[unique(output),]

但是在 R 中,不推荐循环并且(非常)慢,而且我的数据集非常大。您有想法使用更符合 R 的解决方案吗?

4

3 回答 3

2

这是一种矢量化方法:

change.idx <- with(result, which(head(testcase, -1) == tail(testcase, -1) &
                                 head(event,    -1) != tail(event,    -1)))
# [1] 2 4 7 9

keep.idx <- unique(sort(c(change.idx, change.idx + 1)))
# [1]  2  3  4  5  7  8  9 10

result[keep.idx, ]
#     testcase                date  event
# 2  TESTCASE1 2013-06-12 18:12:12 EVENT1
# 3  TESTCASE1 2013-06-12 18:12:15 EVENT2
# 4  TESTCASE1 2013-06-12 18:12:16 EVENT2
# 5  TESTCASE1 2013-06-12 18:12:25 EVENT1
# 7  TESTCASE2 2013-06-12 18:12:16 EVENT4
# 8  TESTCASE2 2013-06-12 18:12:17 EVENT2
# 9  TESTCASE2 2013-06-12 18:12:26 EVENT2
# 10 TESTCASE2 2013-06-12 18:12:30 EVENT1
于 2013-08-01T12:39:29.800 回答
2

这是另一种矢量化方法,使用diff

differs_from_previous <- c(diff(result$event), 0) != 0 & 
    c(diff(result$testcase), 0) == 0
differs_from_next <- c(0, diff(result$event)) != 0 & 
    c(0, diff(result$testcase)) == 0
result[differs_from_previous | differs_from_next, ]

这与from flodel 的方法c(diff(result$event), 0) != 0大致相同。head(testcase, -1) == tail(testcase, -1)

于 2013-08-01T13:15:45.500 回答
2

另外的选择:

f <- function(d) d[with(d, { y <- head(event,-1)!=tail(event,-1); c(FALSE, y) | c(y, FALSE)}),]

Reduce(rbind, by(result, result$testcase, f))

结果

    testcase                date  event
2  TESTCASE1 2013-06-12 18:12:12 EVENT1
3  TESTCASE1 2013-06-12 18:12:15 EVENT2
4  TESTCASE1 2013-06-12 18:12:16 EVENT2
5  TESTCASE1 2013-06-12 18:12:25 EVENT1
7  TESTCASE2 2013-06-12 18:12:16 EVENT4
8  TESTCASE2 2013-06-12 18:12:17 EVENT2
9  TESTCASE2 2013-06-12 18:12:26 EVENT2
10 TESTCASE2 2013-06-12 18:12:30 EVENT1
于 2013-08-01T14:07:45.293 回答