2017-02-26 252 views
4

我遇到以下問題。我想計算小於或等於零的值的出現次數。以下數據中的示例我有3次出現1(0,0,0),2(-1,-2),3(0,0)。 R中是否有函數的構建來計算連續出現的次數。計算出現次數

a <- c(2,4,5,3,2,4,7,0,0,0,4,3,2,-1,-2,3,2,0,0,4) 
+2

@Jaap OP工作似乎要計算運行數項目<= 0,而不是元素的數量。 –

+0

在這種情況下,我有7次發生。我不想總結小於或等於零的值,但是在本例中的系列中出現的數字3 – kelamahim

回答

5

可以使用rle

> sum(rle(a<=0)$values) 
[1] 3 

說明:

rle斷載體引入運行其是> 0或< = 0。$values要麼truefalse這取決於是否或者沒有相應的運行符合謂詞(a <= 0)或其否定。你想對應的值TRUE的運行,如果要算次操作,值低於零的號碼的功能sum要挾那些TRUE s到1

6

:這給

sum(rle(a <= 0)$values) 

[1] 3 

這是如何工作:

  • 使用rle函數可創建a <= 0的遊程長度編碼。
  • rle(a <= 0)輸出是:

    Run Length Encoding 
        lengths: int [1:7] 7 3 3 2 2 2 1 
        values : logi [1:7] FALSE TRUE FALSE TRUE FALSE TRUE ... 
    
  • 現在,你只需要求和rle -object值部分:

    > sum(rle(a <= 0)$values) 
    [1] 3 
    
+0

是否可以使用rle作爲邏輯值?要計算TRUE和FALSE的出現次數? – kelamahim

+0

@kelamahim你的意思是像'rl < - rle(a <= 0);總和(rl $長度[rl $ values])'? – Jaap

+0

我的輸出看起來像:TRUE TRUE TRUE FALSE FALSE TRUE,如此算的真發生,在這種情況下,我有2個 – kelamahim

1

這裏是另一種選擇(不重複相同的東西)使用rleid

library(data.table) 
uniqueN(rleid(a<=0)[a<=0]) 
#[1] 3 

rleid給出的邏輯矢量(a <=0),子集與邏輯矢量([a<=0])的ID,並找到unique ID的lengthuniqueN


或者一個base R的遊程長度-ID方法是

sum(diff(a <=0)==1) 
#[1] 3 
+0

我怎麼能忘了'rleid' ;-) – Jaap

+0

BTW:'總和(DIFF(A <= 0)== 1)'不會當載體用'0開始給正確的輸出' – Jaap

1

使用rle接受的答案是好的,但這裏的另一種方式來做到這一點:

b <- a <= 0 
sum(b) - sum(b[which(b) - 1]) 

此計數非正元件的數量,並減去的多少的這些是由非正元件前面(所以只有非陽性的每次運行的開始結束了貢獻計數。)

我做了一個快速測試,發現它對於大型載體(1000萬到300萬個元素)運行速度快幾倍。

v1 <- function(a) sum(rle(a<=0)$values) 

v2 <- function(a) { 
    b <- a <= 0 
    sum(b) - sum(b[which(b) - 1]) 
} 

v1.time <- NULL 
v2.time <- NULL 
sizes <- 1:30 * 1E7 
for (s in sizes) { 
    x <- sample(-100:100, s, replace = TRUE) 

    v1.time <- c(v1.time, system.time(
    v1.result <- v1(x) 
)[['elapsed']]) 

    v2.time <- c(v2.time, system.time(
    v2.result <- v2(x) 
)[['elapsed']]) 

    print(c(v1.result, v2.result)) # Show that they agree 
    print(v1.time) 
    print(v2.time) 
} 

library(tidyverse) 
data.frame(VectorSize = sizes, 
      v1 = v1.time, 
      v2 = v2.time) %>% 
    gather('Version', 'Time', -VectorSize) %>% 
    ggplot(aes(x = VectorSize, y = Time, color = Version)) + geom_point() + geom_smooth() 

enter image description here

+0

不錯的選擇! – Jaap

0

在這個例子中我怎麼指望在所有複製所有出現的?

set.seed(3) 
b<-c(4,6,4,2,3) 
run<- replicate(2,{ 
a <- runif(5,3,5) 
dif <- a - b 
return(dif) 
}) 
run 
[,1]  [,2] 
[1,] -0.6639169 0.2087881 
[2,] -1.3849672 -2.7507331 
[3,] -0.2301153 -0.4107982 
[4,] 1.6554686 2.1552198 
[5,] 1.2042013 1.2619585 

當我嘗試

sum(rle(run<=0)$values) 

我得到

Error in rle(run <= 0) : 'x' must be a vector of an atomic type 

,但它與

uniqueN(rleid(run<=0)[run<=0])