【问题标题】:R: How to randomly remove data from a matrix while keeping some columns constantR:如何在保持某些列不变的同时从矩阵中随机删除数据
【发布时间】:2021-03-24 10:33:54
【问题描述】:

就上下文而言,我正在尝试测试从社区中移除某些物种对多样性的影响是否与随机移除任何其他物种不同。这个想法是建立一个空模型,在该模型中,我将 df 中某些列中的值保持不变,并将其余部分随机更改为 0。在每一行中,我想将与我保持不变的列数相同的列数更改为 0,以便每行中的数据数等于一行中存在的总数减去每行中的列数。主要问题是每行中要更改为 0 的数据数量会发生变化,因此我必须一次执行一行。

到目前为止,我已经能够使用循环来完成它,但是它很慢,我必须这样做一千次,而且我的实际矩阵要大得多。 在以下示例中,假设我想保留列“V1”、“V7”、“V10”和“V12”:

set.seed(20)
library(picante)
phylo<-rtree(n = ncol(df), tip.label = colnames(df)) #This is needed later for the diversity index
df<-as.data.frame(matrix(data = sample(c(0,1), size = 10*20, replace = T), 
           nrow = 10, ncol = 20))
constant.sps<-c('V1', 'V7', 'V10', 'V12')

我创建用于分隔 dfs,一个包含我想要保留的列 (df1),另一个包含其余列 (df2)。然后根据df1计算我必须在df2中将多少列更改为0,随机选择每行中的那些列并更改它们。之后我加入了 df1 和随机 df 并计算了我需要的多样性度量。然后我必须再做 q 次才能获得每行的多样性度量的零分布。

df1<-df[, colnames(df) %in% constant.sps]
df2<-df[, !colnames(df) %in% constant.sps]
constant.n<-rowSums(df1)

runs<-10
results<-c()
for (q in 1:runs) {
  temp<-df2
  for (i in 1:dim(temp)[1]) {
  temp[i,][sample(which(temp[i,] > 0), constant.n[i])]<-0
  
}
  results[[q]]<-pd(cbind(df1, temp), phylo)[1]
}


这是超级慢且效率低下但我想不出其他方法,有没有人知道如何正确地做到这一点? 提前致谢

【问题讨论】:

    标签: r matrix random shuffle


    【解决方案1】:

    以下是一些建议:

    您可以使用apply 在外循环中进行采样。注意我在这里直接求和而不是使用constant.n

    您还可以通过将序列1:dim(df2)[1] 移到循环外来节省一点时间,这意味着不需要每次都计算。

    runs <- 10
    results <- c()
    rows <- dim(temp)[1]
    
    for (q in 1:runs) {
        temp <- df2
        vals_to_change <- apply(temp, 1, function(x) sample(which(x > 0), sum(x)))
        for(i in 1:rows) {
          temp[i, vals_to_change[[i]]] <- 0
        }
        results[[q]] <- pd(cbind(df1, temp), phylo)[1]
      }
    

    这将时间大约缩短了一半(以 100 次运行为基准):

    # A tibble: 2 x 13
      expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc
      <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>
    1 new()      766.48ms 766.48ms     1.30     19.7MB     2.61     1     2
    2 old()         1.54s    1.54s     0.650      21MB     1.30     1     2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多