代码之家  ›  专栏  ›  技术社区  ›  Roald

围绕NA值对向量的部分顺序重新排序

  •  0
  • Roald  · 技术社区  · 7 年前

    我有一个大的数据集,我想使用R中的sample()函数以12个为一组重新排序,以生成随机数据集,我可以用这些数据集进行置换测试。但是,这些数据具有NA字符,无法收集数据,我希望在数据被洗牌时,它们保持在各自的原始位置。

        example.data <- c(0.33, 0.12, NA, 0.25, 0.47, 0.83, 0.90, 0.64, NA, NA, 1.00, 0.42)
    
        example.data[!is.na(example.data)] <- sample(example.data[!is.na(example.data)], replace = F, prob = NULL)
    
    [1] 0.64  0.83  NA  0.33  0.47  0.90  0.25  0.12  NA  NA  0.42  1.00
    

    例如,从第一个示例延伸的向量:

    example.data <- c(0.33, 0.12, NA, 0.25, 0.47, 0.83, 0.90, 0.64, NA, NA, 1.00, 0.42, 0.73, NA, 0.56, 0.12, 1.0, 0.47, NA, 0.62, NA, 0.98, NA, 0.05)
    

    example.data[1:12] example.data[13:24] NA 价值观

    我试图将此解决方案转化为以下代码:

    shuffle.data = function(input.data,nr,ns){
    simdata <- input.data
      for(i in 1:nr){
        start.row <- (ns*(i-1))+1
        end.row   <- start.row + actual.length[i] - 1
        newdata = sample(input.data[start.row:end.row], size=actual.length[i], replace=F)
        simdata[start.row:end.row] <- newdata
          }
    return(simdata)}
    

    哪里 input.data 是原始输入数据( example.data nr 是组数(2), ns actual.length NAs 存储在向量中( actual.length <- c(9, 8)

    有人知道如何实现这一点吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   duckmayr    7 年前

    我同意 Gregor 但是,即使所有数据都在一个向量中,你需要完成的事情仍然可以很容易地完成。

    shuffle_real <- function(data){
      # Sample from only the non-NA values,
      # and store the result only in indices of non-NA values
      data[!is.na(data)] <- sample(data[!is.na(data)])
      # Then return the shuffled data
      return(data)
    }
    

    现在编写一个函数,该函数接受较大的向量,并将该函数应用于向量中的每个组:

    shuffle_groups <- function(data, groupsize){
      # It will be convenient to store the length of the data vector
      N <- length(data)
      # Do a sanity check to make sure there's a match between N and groupsize
      if ( N %% groupsize != 0 ) {
        stop('The length of the data is not a multiple of the group size.',
             call.=FALSE)
      }
      # Get the index of every first element of a new group
      starts <- seq(from=1, to=N, by=groupsize)
      # and for every segment of the data of group 'groupsize',
      # apply shuffle_real to it;
      # note the use of c() -- otherwise a matrix would be returned,
      # where each column is one group of length 'groupsize'
      # (which I note because that may be more convenient)
      return(c(sapply(starts, function(x) shuffle_real(data[x:(x+groupsize-1)]))))
    }
    

    example.data <- c(0.33, 0.12, NA, 0.25, 0.47, 0.83, 0.90, 0.64, NA, NA, 1.00,
                      0.42, 0.73, NA, 0.56, 0.12, 1.0, 0.47, NA, 0.62, NA, 0.98,
                      NA, 0.05)
    
    set.seed(1234)
    
    shuffle_groups(example.data, 12)
    

    这导致

    > shuffle_groups(example.data, 12)
     [1] 0.12 0.83   NA 1.00 0.47 0.64 0.25 0.33   NA   NA 0.90 0.42 0.47   NA
    [15] 0.05 1.00 0.56 0.62   NA 0.73   NA 0.98   NA 0.12
    

    shuffle_groups(example.data[1:23], 12) Error: The length of the data is not a multiple of the group size.