【问题标题】:Repeat values in fixed number of rows in dataframe in R在R中数据框中的固定行数中重复值
【发布时间】:2016-06-10 13:47:40
【问题描述】:

我有一个由 168 个文件名组成的数据框 DF1

DF1$FileName <- c("File1.csv", "File2.csv",..... "File168.csv")

使用:

filez <- NULL
for (i in 1:168){
     filez[i] <- paste0("file", i, ".csv", sep="")
}
filesz <- as.data.frame(filez)

我有另一个数据框 DF2 如下:

DF2$RowNumber <- as.data.frame(rep(c(1:512000), times = 168, length.out = NA, each = 1))

这意味着 DF2 有一列“RowNumber”,其中数字 1 到 512000 重复了 168 次(即总共 86016000 行)。

我想做的是:

  1. 选择一个文件名(一次一个)-> DF1$FileName[i]

  2. 然后在 DF2$FileName 中重复粘贴 1 到 512000

  3. 重复上述操作,直到86016000行全部填满

最终结果应如下所示:

DF2
RowNumber     FileName
1             File1.txt    
2             File1.txt
3             File1.txt
.             .
.             .
.             .
.             .
512000        File1.txt
1             File2.txt
2             File2.txt
3             File2.txt
.             .
.             .
512000        File2.txt
1             File3.txt
2             File3.txt
3             File3.txt
.             .
.             .
512000        File3.txt
.             .
.             .
512000        File167.txt
1             File168.txt
2             File168.txt
3             File168.txt
.             .
.             .
512000        File168.txt

我试过这个,但我知道有逻辑错误导致系统挂起:

for (i in 1:nrow(m)){
    while(m$RowNumber[i] != 512000) {m$FileName[i] <- filez[[i]]}
}

有人可以建议我更好更简单的方法来解决我的问题吗?

我确信 R 会有一些包来执行这些操作,但我不知道是哪一个。

【问题讨论】:

    标签: r dataframe row repeat


    【解决方案1】:

    在这种情况下不需要for 循环。您可以为此使用专门设计的功能,例如:

    1) expand.grid 来自基础 R:

    filenames <- paste0("file", 1:168, ".csv")
    rownumbers <- 1:512000
    
    d <- expand.grid(rownumbers = rownumbers, filenames = filenames)
    

    给出:

    > head(d)
      rownumbers filenames
    1          1 file1.csv
    2          2 file1.csv
    3          3 file1.csv
    4          4 file1.csv
    5          5 file1.csv
    6          6 file1.csv
    

    2) data.table 包中的CJ(交叉连接)函数:

    library(data.table)
    d <- CJ(rownumbers = rownumbers, filenames = filenames)
    

    这会给你同样的结果。

    3) tidyr 包中的 crossing 函数:

    library(tidyr)
    d <- crossing(rownumbers = rownumbers, filenames = filenames)
    

    这也会给你同样的结果。

    【讨论】:

    • 嗨,Jaap。感谢您的解决方案。但我想,应该是:df1
    • @MANU 通过使用rownumbers = rownumbers,您可以确保将直接命名列。如果没有必要,使用df1 &lt;- expand.grid(rownumbers, filenames)d &lt;- CJ(rownumbers, filenames) 就足够了。
    • @Japp:假设我仍然必须从 DF1 一次选择一个文件名,代码应该是什么样子?我将不得不使用循环,对吧?
    • @MANU 你为什么要那样做?在这种情况下,使用 for 循环会无限慢。
    • '@Japp 是的,伙计,谢谢。我所做的是对您的代码进行了一些小调整: filenames 效果很好。非常简单的方法。
    【解决方案2】:

    最简单的方法是使用整数除法:

    for(i in 1:nrow(m)) {
        filenum = 1+floor((i-1)/512000)
        filename = paste0("File",filenum,".txt")
        ## instead of : m$FileName[i]=filenum , use:
        m$FileName[i] = filename  ## it works!
    }
    

    希望对你有帮助

    【讨论】:

    • 假设,由于某些原因,我不能按照您的建议在 for 循环中使用 filename = paste0("File",filenum,".txt"),我应该如何调用 filename (即一次来自其他数据帧的一个文件名)以将其重复到循环中?
    猜你喜欢
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-12-15
    • 2020-04-03
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    相关资源
    最近更新 更多