将相似数量的矢量分组

时间:2015-06-16 11:32:35

标签: r

假设我有以下向量:

c(4, 5, 5, 8, 12, 12, 12, 13, 15, 15, 18, 19, 20, 23, 37, 37, 37, 37, 37, 41)

我想根据它们的值“分组”它们的元素:不同的数字< = 3应该被认为属于同一个组。 在这种情况下,我希望,对于向量中出现的每个数字,获取所有接近它的数字。 例如,

4  -->  c(4,5,5,8)
5  -->  c(4,5,5,8)
8  -->  c(5,8)
12 -->  c(12,12,12,13,15,15)

可能,获取他们的索引也很有用...... 有没有聪明的方法来实现这个目标?

4 个答案:

答案 0 :(得分:9)

你可以使用这个小功能:

similar <- function(vec, val, bound = 3, index = F) {
    close.index <- which(abs(vec - val) <= bound)
    if (index) return(close.index)
    return(vec[close.index])
}

x <- c(4, 5, 5, 8, 12, 12, 12, 13, 15, 15, 18, 19, 20, 23, 37, 37, 37, 37, 37, 41)
similar(x, 5)
# [1] 4 5 5 8
similar(x, 5, index = T)
# [1] 1 2 3 4
similar(x, 5, bound = 7)
# [1]  4  5  5  8 12 12 12

答案 1 :(得分:2)

也许不是最优雅的版本,但这会做你想要的吗?

abs

使用for (i in 1:length(vals)) print(which(abs(x-vals[i]) <= 3)) for (i in 1:length(vals)) print(x[which(abs(x-vals[i]) <= 3)]) 确实有点优雅。

# import "GoogleMapsM4B/GoogleMaps.h"

答案 2 :(得分:2)

这是一个简短的解决方案,为您提供所有组列表:

x = c(4, 5, 5, 8, 12, 12, 12, 13, 15, 15, 18, 19, 20, 23, 37, 37, 37, 37, 37, 41)

m = unique(x)
setNames(apply(abs(outer(m,m,'-')), 2, function(u) m[u<=3]),m)

#$`4`
#[1] 4 5

#$`5`
#[1] 4 5 8

#$`8`
#[1] 5 8

#$`12`
#[1] 12 13 15

#$`13`
#[1] 12 13 15

#$`15`
#[1] 12 13 15 18

#$`18`
#[1] 15 18 19 20

#$`19`
#[1] 18 19 20

#$`20`
#[1] 18 19 20 23

#$`23`
#[1] 20 23

#$`37`
#[1] 37

#$`41`
#[1] 41

对于索引,可以轻松应用相同的概念:

setNames(apply(abs(outer(m,m,'-')), 2, function(u) which(x %in% m[u<=3])),m)

答案 3 :(得分:0)

使用数字作为“键”创建列表可能会有所帮助:

data <- c(4, 5, 5, 8, 12, 12, 12, 13, 15, 15, 18, 19, 20, 23, 37, 37, 37, 37, 37, 41)
uniques <- unique(data)

myGroups <- lapply(
  uniques,
  function(n) Filter(
    function(x) abs(x - n) <= 3,
    data
  )
)
names(myGroups) <- uniques


myIndices <- lapply(
  uniques,
  function(n) which(abs(data - n) <= 3)
)
names(myIndices) <- uniques

然后,要访问“12”的组和索引,请说:

> myGroups[['12']]
[1] 12 12 12 13 15 15
> myIndices[['12']]
[1]  5  6  7  8  9 10