【问题标题】:Use of for next loop to introduce blanks at random in large matrix, R使用 for next 循环在大矩阵 R 中随机引入空白
【发布时间】:2021-09-06 06:39:02
【问题描述】:

我有一个大矩阵,n x m,其中 m - 不。列中,数据集称为数据。实际上,ncol 的范围可以从 80 到 200 列。

我想引入随机缺失的单元格值,例如每列中的 1%,使用

res<-do.call(cbind,lapply(lapply(data[,1:ncol(data)],function(x) data.frame(x)),function(x) x[sample(1:nrow(x),0.01*nrow(x)),]))

缺失的单元格将包含 NA,使用

data[,1][data[,1]%in%res[,1]]<- NA

其中 [,1] 是第 1 列。如果没有。 [ncol] 的列数为 5,我可以通过每次更改上述等式中的数字来手动完成。如果说有 50 列,这将非常耗时。如果 200 列或更多列....

我尝试使用 for/next 循环,即

ncol(data)  
n = length(ncol(data))

for (i in 1:n)

{

  data[,i][data[,i]%in%res[,i]]<- NA
  
}

但这不起作用 - 没有插入随机 NA。

我的问题 -

[1] 如何使用 for/next 循环在 n x m 矩阵中生成 0.1%、1% 和 5% 的随机 NA?

[2] 我毫不怀疑有一种更有效的方法可以做到这一点,但到目前为止我还没有运气。最好的方法是什么?

[3] 如果我采用手动方法,则列内容会根据需要进行更改。有没有办法保存更改的[即现在包含随机 NAs] n x m 矩阵?

【问题讨论】:

  • n = length(ncol(data)) 将始终返回 1,因为 ncol(data) 已经对列进行计数并返回一个整数。 length() 然后获取这个整数并返回 1...

标签: r for-loop matrix random na


【解决方案1】:

ktiu 已经提供了答案,但要澄清为什么您的代码不起作用以及如何修复它并解决您的问题 (1):

n <- ncol(data)

for(i in 1:n){
random_rows <- sample(1:nrow(data), 0.01*nrow(data))
data[random_rows, i] <- NA
}

请注意 1) ncol(data) 已经为您提供了列数。 现在您可以使用for 循环遍历所有列,并在每一列中生成行索引的随机样本。然后只需将i 列中的那些行设置为 NA。

使用apply 比使用循环要快得多,但是对于初学者来说并不那么直观。

问题(3)取决于您要如何保存矩阵。有很多方法可以在 R 中保存数据,例如您可以将它们保存为RDA or RDATA,或者您可以将它们保存为export them as csv 文件甚至as Excel file。 (请注意,这需要安装和加载相应的包。)

关于您的评论,我认为这应该可行:

n <- ncol(data)

for(i in 1:n){
random_number <- runif(1, min = 0.001, max = 0.05)
random_rows <- sample(1:nrow(data), round(random_number*nrow(data), digits = 0))
data[random_rows, i] <- NA
}

在这里,我们只生成一个介于 0.001 和 0.05 之间的随机数,并将该数字用作该列的 NA 值的份额。我将计算(共享*行数)包装在round() 中,以确保结果数字是整数(sample() 函数也接受非整数值作为要选择的样本数,但在这种情况下它将始终向下取整,从不向上取整,这使得 5% 的可能性低于其他可能的值,我猜)。

【讨论】:

  • 嗨,Manuel,这非常有见地和帮助,谢谢。如果我可以将其提升到一个新的水平 - 如果有 n 列,我如何在不同程度上将 NA 引入每一列?换句话说,每列可以包含不同数量的 NA,介于 0.1 和 5% 之间,随机生成。
  • 我为我的答案添加了一个解决方案。基本上,您只需将代码中的 0.01 替换为 0.001 到 0.05 之间的随机数,可以使用 runif() 生成。
  • 谢谢你 手册,我离你的解决方案还有点距离。熟能生巧。
【解决方案2】:

我希望这种方法能解决您的一些问题:

采用一个包含 100 列、每列 200 个值的大型矩阵

data <- matrix(runif(20000), ncol = 100)

你可以的

apply(data, 2, \(c) {
   na_positions <- sample(1:length(c), 0.01 * length(c))
   c[na_positions] <- NA
   return(c)
}) -> data_with_na

验证前四列的结果:

summary(data_with_na[, 1:4])
       V1                 V2                  V3                 V4         
 Min.   :0.004131   Min.   :0.0009613   Min.   :0.004394   Min.   :0.00178  
 1st Qu.:0.246076   1st Qu.:0.2334719   1st Qu.:0.224328   1st Qu.:0.20329  
 Median :0.499454   Median :0.4686971   Median :0.458352   Median :0.49704  
 Mean   :0.501149   Mean   :0.4868858   Mean   :0.482523   Mean   :0.48674  
 3rd Qu.:0.767258   3rd Qu.:0.7511260   3rd Qu.:0.756019   3rd Qu.:0.72742  
 Max.   :0.997355   Max.   :0.9889819   Max.   :0.993775   Max.   :0.99797  
 NA's   :2          NA's   :2           NA's   :2          NA's   :2        

【讨论】:

  • 感谢大家分享您的专业知识,非常感谢。我注意到初学者的评论,非常外交:-)。 ktiu - 我无法让你的方法工作,返回以下错误 -> apply(data, 2, (c) { Error: unexpected input in "apply(data, 2, \" > na_positions c[na_positions] return(c) 错误:没有函数从返回,跳转到顶层 > }) -> data_with_na 错误:“}”中的意外'}'。你能指出为什么吗?谢谢。
  • 您使用的不是最新版本的 R (4.1)。可以升级或替换第一行为apply(data, 2, function(c) {
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-11
  • 2013-07-30
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多