Randomly associate elements of two vectors given conditions

前端 未结 5 740
心在旅途
心在旅途 2021-01-23 18:26

I have a data.table of capitals

capitals<-data.table(capital=c(100,50,25,5))
capitals
   capital
1:     100
2:      50
3:      25
4:       5
         


        
5条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-23 18:48

    Try this for small vectors:

    capital=c(100,50,25,5)
    loss=c(45,10,5,1)
    
    posC<- order(capital)
    posC
    
    lossN <- NULL
    
    for(i in posC){
      temp <- sample(which(loss<=capital[i]),1)
      lossN <- c(lossN, loss[temp])
      loss <-loss[-temp]
    }
    
    
    data.table(capital=capital,loss=lossN[posC])
    

    EDIT

    This one is for large vectors:

    set.seed(100)
    loss=sort(sample(1:5000,100000,replace = T))
    capitals = sort(sample(1:100000,100000,replace=T))    
    
    capU <- unique(capitals)
    length(capU)
    
    splitLoss <- split(loss,findInterval(loss,sort(c(0,capU))))
    head(splitLoss)
    splitCap <- split(capitals,findInterval(capitals,sort(c(0,capU))))
    head(splitCap)
    
    lossN <- NULL
    temp <- NULL
    
    for(i in 1:length(splitLoss)){  
      temp <- c(temp,splitLoss[[i]])  
      for(j in 1:length(splitCap[[i]])){
        id <- sample(1:length(temp),1)
        lossN <- c(lossN, temp[id])
        temp <-temp[-id]      
      }
    }
    
    lossN <- c(lossN,ifelse(length(temp)==1,temp,sample(temp)))
    data.table(capital=capitals,loss=lossN)
    

    This takes about 7 sec on my machine. The only assumption here is that capitals is sorted and increasing. If needed you can use the order function to make this work for unordered values of capitals in two more lines.

    Hope this helps!!

提交回复
热议问题