【问题标题】:Delete row after row in for loop在for循环中逐行删除
【发布时间】:2014-05-05 19:59:31
【问题描述】:

我有一个大字符向量file,我需要从中抽取一个随机样本。这工作正常。但我需要一个接一个地抽取样本。为此,我想通过已经从中提取的每个元素来缩短 file(我可以绘制一个新样本而无需多次绘制相同的元素)。

我有一些解决方案,但我对其他可能更快、甚至更重要的方法感兴趣,也许是正确的。

这是我的尝试:

方法 1

file <- rep(1:10000)
rand_no <- sample(file, 100)

library(car)
a <- data.frame()

for (i in 1:length(rand_no)){
     a <- rbind(a, which.names(rand_no[i], file))
     file <- file[-a[1,1]]
}

问题:

Warning message:
In which.names(rand_no[i], file) : 297 not matched

方法 2

file <- rep(1:10000)
rand_no <- sample(file, 100)

library(car)
deleter <- function(i) {
   a <- which.names(rand_no[i], file)
   file <- file[-a]
}

lapply(1:length(rand_no), deleter)

问题: 这根本行不通。也许我应该拆分问题,因为第二个问题显然在于我没有完全理解lapply

感谢您的任何建议。

编辑

我希望它适用于数字,但当然file 看起来像这样:

file <- c("Post-19960101T000000Z-1.tsv", "Post-19960101T000000Z-2.tsv", "Post-19960101T000000Z-3.tsv","Post-19960101T000000Z-4.tsv", "Post-19960101T000000Z-5.tsv", "Post-19960101T000000Z-6.tsv", "Post-19960101T000000Z-7.tsv","Post-19960101T000000Z-9.tsv")

当然rand_no 不能超过 100 个文件,样本如此之少。因此:

 rand_no <- sample(file, 2)

【问题讨论】:

    标签: r for-loop lapply


    【解决方案1】:

    使用list 代替c。然后您可以将值设置为NULL,它们将被删除。

    file[file %in% rand_no] &lt;- NULL 这会在file 中查找来自rand_no 的所有实例并将它们删除。

    file <- list("Post-19960101T000000Z-1.tsv",
     "Post-19960101T000000Z-2.tsv",
     "Post-19960101T000000Z-3.tsv",
     "Post-19960101T000000Z-4.tsv",
     "Post-19960101T000000Z-5.tsv",
     "Post-19960101T000000Z-6.tsv",
     "Post-19960101T000000Z-7.tsv",
     "Post-19960101T000000Z-9.tsv")
    rand_no <- sample(file, 2)
    
    library(car) #From poster's code.
    
    file[file %in% rand_no] <- NULL
    

    如果您正在处理大量文件,使用%in% 比较字符串可能会让您陷入困境。在这种情况下,我会使用索引。

    file <- list("Post-19960101T000000Z-1.tsv",
                 "Post-19960101T000000Z-2.tsv",
                 "Post-19960101T000000Z-3.tsv",
                 "Post-19960101T000000Z-4.tsv",
                 "Post-19960101T000000Z-5.tsv",
                 "Post-19960101T000000Z-6.tsv",
                 "Post-19960101T000000Z-7.tsv",
                 "Post-19960101T000000Z-9.tsv")
    rand_no <- sample(1:length(file), 2)
    
    library(car) #From poster's code.
    
    file[rand_no] <- NULL
    

    【讨论】:

    • 这太天才了!谢谢。
    • 你为什么有library(car)?当然,这确实假设所有文件名都是唯一的。如果不确定,选择索引而不是实际值会更安全。
    【解决方案2】:

    Sample() 已经以没有替换的排列顺序返回值(除非您设置 replace=T)。所以它永远不会选择两次。

    所以如果你想要三组不共享任何元素的 100 个样本,你可以使用

    file <- rep(1:10000)
    rand_no <- sample(seq_along(file), 300)
    
    s1<-file[rand_no[1:100]]
    s2<-file[rand_no[101:200]]
    s3<-file[rand_no[201:300]]
    

    或者,如果您希望每次可以将总大小减小 100

    s1<-file[-rand_no[1:100]]
    s2<-file[-rand_no[1:200]]
    s3<-file[-rand_no[1:300]]
    

    【讨论】:

      【解决方案3】:

      一种简单的方法是选择随机索引,然后删除这些索引:

      file <- 1:10000  # Build sample data
      ind <- sample(seq(length(file)), 100)  # Select random indices
      rand_no <- file[ind]  # Compute the actual values selected
      file <- file[-ind]  # Remove selected indices
      

      【讨论】:

        【解决方案4】:

        我认为使用samplesplit 可能是一种很好的方法,而无需更改您的files 变量。除非您真的需要,否则我不是突变的忠实拥护者,这可以让您确切地知道您在接下来的每个分析块中使用了哪些文件。

        files<-paste("file",1:100,sep="_")     
        randfiles<-sample(files, 50)
        randfiles_chunks<-split(randfiles,seq(1,length(randfiles), by=10))
        

        【讨论】:

          猜你喜欢
          • 2016-04-25
          • 2022-10-20
          • 2013-06-26
          • 2023-04-10
          • 1970-01-01
          • 2022-07-21
          • 1970-01-01
          • 1970-01-01
          • 2017-09-13
          相关资源
          最近更新 更多