在列表中的元素周围移动

时间:2018-04-20 13:47:21

标签: r

我的一般性问题涉及有效地改变列表中的元素。

说我有一个清单:

region <- list(c(1,3,2,6),c(5,8,9),c(10,4,7))

和两个常数:

value <- 2
swapin <- 5

我想做两件事。我想从列表中的向量中删除element ==值,然后将其添加到该向量的第一个元素== swapin

的向量中

结果如下:

region <- list(c(1,3,6),c(5,8,9,2),c(10,4,7))

第一步,我能想到的唯一方法是做这样的事情:

region <- lapply(1:length(region), function(x) region[[x]][region[[x]] != value])

但这似乎效率低下。我的实际数据可能涉及一个非常大的列表,这种方法似乎很麻烦。是否有一个避免循环的简单技巧?

对于第二步,我可以创建一个像这样的更新向量:

updated <- c(unlist(region[sapply(region, `[`, 1)==swap]),best)

但我对如何用更新的矢量c(5,8,9,2)替换当前列表中的向量c(5,8,9)感到困惑。也许我可以更简单地添加元素?

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

这样的事情可以解决问题:

region <- list(c(1,3,2,6),c(5,8,9),c(10,4,7))

value <- 2
swapin <- 5

step1 = lapply(region, function(x) x[x != value])

step2 = lapply(step1, function(x){
  if(x[1]==swapin){
    return(c(x, value))
  } else {
    return(x)
  }
})

不是通过输入它的元素索引来循环遍历region,而是可以循环遍历region本身。这实际上是如何使用lapply - 将函数应用于列表的每个元素。如果x的第一个元素与x匹配,或者value本身,则第二步用x + swapin替换每个元素x如果swapin不匹配。

<强>结果:

> step2
[[1]]
[1] 1 3 6

[[2]]
[1] 5 8 9 2

[[3]]
[1] 10  4  7

您还可以轻松地将其作为便利功能供以后使用:

element_swap = function(list, value, swapin){

  step1 = lapply(list, function(x) x[x != value])

  step2 = lapply(step1, function(x){
    if(x[1]==swapin){
      return(c(x, value))
    } else {
      return(x)
    }
  })

  return(step2)

}

<强>结果:

> element_swap(region, 1, 10)
[[1]]
[1] 3 2 6

[[2]]
[1] 5 8 9

[[3]]
[1] 10  4  7  1