1

我有一个看起来像这样的列表:

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) == 2and length(list.1$c)==3,我想用于list.1$b从 and 中随机化值,以及从list.1$aand中list.1$c随机化list.1$c值。任何想法如何实现这一目标?list.1$blist.1$d

提前谢谢了

更新

为@dardisco 提供的解决方案:

l2 <- list()
ll1 <- length(list.1)
length(l2) <- ll1
set.seed(4)
for (i in 1:ll1){
   vec1 <- list.1[[i]]
    jl <- 1;jr<-1; #i've added two counters one for left one for right
    while (length(vec1) < 4){
       if(i==1) {
          vec1 <- c(vec1, list.1[[i+jr]])
          jr <- jr+1
        } else if (i==ll1 || jr+i==ll1 ){ #to avoid out of boundaries, so many elements with less than 4 elements close to the end
           vec1 <- c(vec1, list.1[[i-jl]])
           jl <- jl+1
    }else {
           vec1 <- c(vec1, list.1[[i-jl]], list.1[[i+jr]])
               jl <- jl+1
        jr <- jr+1
        } 
 } 
   l2[[i]] <- sample2(vec1, 10, replace=TRUE)   
}
4

1 回答 1

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)
            }
    }

请注意,这假定列表中的第一个和最后一个元素具有 >=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)
}

这应该做你想做的事,尽管可能有更漂亮的方式。矢量化的收益可能充其量是适度的。

于 2013-06-22T04:02:19.297 回答