计算和排列列表中的元素

时间:2013-06-21 18:26:56

标签: r

我有一个如下所示的列表:

list.1 <- list(a=c(0.1,0.2,0.2,0.3,0.12), 
             b=c(0.1,0.2), 
             c=c(0.3,0.1,0.2), 
             d=c(0.1,0.3,0.4,0.5))

我希望从list.1生成一个包含随机(置换)值的新列表,我的方法如下:

rand.list <- lapply(list.1, FUN=function(x) replicate(10, sample(x,1)))

但是,如果列表中元素的长度小于数字,例如4,那么我想在列表中使用其他元素(上一个和下一个)来计算排列,同时考虑到<所有这些元素的长度> 4.例如,在我的列表length(list.1$b) == 2length(list.1$c)==3中,我想使用来自list.1$blist.1$a的{​​{1}}值随机化,并用于随机化来自list.1$clist.1$c的{​​{1}}值。任何想法如何实现这个??

非常感谢提前

更新

提供@dardisco的解决方案:

list.1$b

1 个答案:

答案 0 :(得分:1)

来自@DWins的建议 - 您正在寻找什么?

l2 <- list()
length(l2) <- length(list.1)
set.seed(1)
for (i in 1:length(list.1)){
    if ( length(list.1[[i]]) >=4 ){
        l2[[i]] <- sample(list.1[[i]], 10, replace=TRUE)
        } else {
            l2[[i]] <- sample(c(list.1[[i]],list.1[[i-1]],list.1[[i+1]]),
                                10, replace=TRUE)
            }
    }

请注意,这假设列表中的第一个和最后一个元素具有&gt; = 4个元素。

<强>更新

根据您的评论 - 从一个更好地说明问题的示例开始:

list.1 <- list(a=letters[1:2],
               b=letters[3],
               c=letters[10:14],
               d=letters[25:26])

然后

l2 <- list()
ll1 <- length(list.1)
### ll1 = length of list.1
length(l2) <- ll1
set.seed(4)
for (i in 1:ll1){
### vec1 = default vector from which to sample
    vec1 <- list.1[[i]]
### j = counter for position relative to current
    j <- 1
### if sample size <4 (the threshold) then include additional elements in list until >=4
### change this to 50 if required, as in:
### while (length(vec1) <50){
    while (length(vec1) <4){
### check if at first element
        if(i==1) {
### keep adding successive elements from list.1 to end of vec1
            vec1 <- c(vec1, list.1[[i+j]])
            j <- j+1
### if at last element, add preceding elements
        } else if (i==ll1 ){
            vec1 <- c(vec1, list.1[[i-j]])
            j <- j+1
        } else {
### you could add both in one step, like so:
### vec1 <- c(vec1, list.1[[i-j]], list.1[[i+j]])
### j <- j+1
### }
### or do it in two steps as below:
###
### k = counter to indicate moving forward or back 
            k <- 1
### if odd, add next element
            if (!k %% 2==0){
                vec1 <- c(vec1, list.1[[i+j]])
            } else {
### if even, add preceding element and increment counter for relative position
                vec1 <- c(vec1, list.1[[i-j]])
                j <- j+1
            }
            k <- k+1
        }
    }
    l2[[i]] <- sample(vec1, 10, replace=TRUE)
}

这应该做你想要的,尽管可能有更漂亮的方式。矢量化的收益最多可能是温和的。