簡體   English   中英

R中的all.different函數,是否將其循環應用?

[英]all.different function in R, apply it in a loop?

我有一個數字向量。 例如這樣,只有幾個唯一值:

set.seed(2)
a = rpois(1000, 0.3)
head(a, 20)
#### [1] 0 0 0 0 1 1 0 1 0 0 0 0 1 0 0 1 2 0 0 0

現在,我需要為每個數字查找( 如果本身),則前一個和后一個元素都不同 我試圖在R中找到一個all.different或all different函數,但是沒有成功,所以我做到了:

all.diff = function(num) NROW(unique(num))==NROW(num)

然后我想到了這樣的for循環:

ConsecutiveDifferent = function(vector) {
  output = numeric(NROW(vector)-2)
  for (i in 2:(NROW(vector)-1) ) {
    trio <- c(vector[i-1], vector[i], vector[i+1])
    if ( all.diff(trio) ) output[i]<-1
  }
  return(output)
}
res = ConsecutiveDifferent(a)
head(res, 20)
#### [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0

它可以完成工作,但是由於向量的長度為數億,所以我想知道是否有比循環更好的方法。

謝謝,

編輯

感謝您給我這么多解決方案! 我無法決定必須接受誰的答案,所以我做了一個微型標記(長度= 50000),獎品歸弗朗克所有。 在此處輸入圖片說明

RLE。 這對於三重奏非常特殊:

w = with(rle(a), cumsum(lengths)[ 
  lengths == 1L & c(NA, values[-length(values)]) != c(values[-1], NA)
])

res2    = c(NA, logical(length(a)-2), NA)
res2[w] = TRUE

identical(res, res2) # TRUE

combn。 我可能會做

a_shift    = list(c(NA, a[-length(a)]), a, c(a[-1], NA))
n_distinct = rowSums(combn(a_shift, 2, FUN = function(x) x[[1]] != x[[2]]))
res        = n_distinct == length(a_shift)

要檢查它是否有效...

head(cbind.data.frame(a, res), 20)


   a   res
1  0    NA
2  0 FALSE
3  0 FALSE
4  0 FALSE
5  1 FALSE
6  1 FALSE
7  0 FALSE
8  1 FALSE
9  0 FALSE
10 0 FALSE
11 0 FALSE
12 0 FALSE
13 1 FALSE
14 0 FALSE
15 0 FALSE
16 1  TRUE
17 2  TRUE
18 0 FALSE
19 0 FALSE
20 0 FALSE

可以通過擴展a_shift將其擴展為向前和a_shift ,可以使用data.table中的shift函數輕松完成:

library(data.table)
n_back = 1
n_fwd  = 1
a_shift = setDT(list(a))[, c(
  shift(V1, n_back:0, type="lag"), 
  list(shift(V1, n_fwd, type="lead"))
)]
a_shift[, r := .I]

resDT = melt(a_shift, id = "r")[, .(res = 
  if (any(is.na(value))) NA else uniqueN(value) == n_fwd + n_back + 1L
), by=r][, a := a]

 identical(res, resDT$res) # TRUE

...可能看起來很神秘,但這與我的編碼風格有關,而不是與程序包有關。

以下步驟不使用迭代器函數(像函數一樣應用),我認為它會更快

 da = diff(a)
 lda = c(0,da)
 rda = c(da,0)
 sda = lda + rda
 res = lda != 0 & rda != 0 & sda != 0

res在第一個和最后一個位置包含FALSE ,並且其長度與向量a相同。

您可以使用duplicated功能

adjacent_dif <- function(i,l){
  as.numeric(!any(duplicated(c(l[i-1], l[i], l[i+1]))))
}

sapply(2:length(a)-1, adjacent_dif, a)

丑陋如罪,但行之有效。

set.seed(2)
a <- rpois(1000, 0.3)

a_shifted <- embed(a,3)

indices <- 1 + which(apply(X = a_shifted,
                           FUN = function(num) {length(unique(num))==length(num)},
                           MARGIN = 1))
print(a[indices])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM