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) == 2andlength(list.1$c)==3を使用して、 とlist.1$bから値をランダム化list.1$alist.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 に答える