围绕 NA 值顺序重新排序向量的部分
Sequentially re-ordering sections of a vector around NA values
我有一大组数据,我想使用 R 中的 sample() 函数以十二个为一组重新排序,以生成随机数据集,我可以用这些数据集进行排列测试。但是,此数据具有无法收集数据的 NA 字符,我希望它们在数据打乱后保持在各自的原始位置。
在上一个问题的帮助下,我已经设法使用代码将 NA 值周围的数据打乱为一个包含 24 个值的向量:
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
由此扩展,如果我有一组长度为 24 的数据,我将如何将第一组和第二组 12 个值作为循环中的个别情况重新排序?
例如,从第一个示例延伸的向量:
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
是每个样本的大小(12); actual.length
是每个组的长度,不包括存储在向量中的 NAs
(上例中的 actual.length <- c(9, 8)
)。
有人知道如何实现吗?
再次感谢您的帮助!
我同意 Gregor 的评论,即以另一种形式处理数据可能是更好的方法。但是,即使所有数据都在一个向量中,您仍然可以轻松完成您需要完成的工作。
首先创建一个仅对整个向量的非 NA 值进行混洗的函数:
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.
我有一大组数据,我想使用 R 中的 sample() 函数以十二个为一组重新排序,以生成随机数据集,我可以用这些数据集进行排列测试。但是,此数据具有无法收集数据的 NA 字符,我希望它们在数据打乱后保持在各自的原始位置。
在上一个问题的帮助下,我已经设法使用代码将 NA 值周围的数据打乱为一个包含 24 个值的向量:
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
由此扩展,如果我有一组长度为 24 的数据,我将如何将第一组和第二组 12 个值作为循环中的个别情况重新排序?
例如,从第一个示例延伸的向量:
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
是每个样本的大小(12); actual.length
是每个组的长度,不包括存储在向量中的 NAs
(上例中的 actual.length <- c(9, 8)
)。
有人知道如何实现吗?
再次感谢您的帮助!
我同意 Gregor 的评论,即以另一种形式处理数据可能是更好的方法。但是,即使所有数据都在一个向量中,您仍然可以轻松完成您需要完成的工作。
首先创建一个仅对整个向量的非 NA 值进行混洗的函数:
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.