R中数据框中固定行数的重复值
Repeat values in fixed number of rows in dataframe in R
我有一个数据框 DF1 由 168 个文件名组成:
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 行)。
我想做的是:
Select 一个文件名(一次一个)-> DF1$FileName[i]
并在 DF2$FileName
中重复粘贴 1 到 512000
重复以上操作直到所有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 会有一些包来执行此类操作,但我不知道是哪一个。
在这种情况下不需要 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)
这也会给你相同的结果。
最简单的方法是使用整数除法:
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!
}
希望对您有所帮助
我有一个数据框 DF1 由 168 个文件名组成:
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 行)。
我想做的是:
Select 一个文件名(一次一个)-> DF1$FileName[i]
并在 DF2$FileName
中重复粘贴 1 到 512000
重复以上操作直到所有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 会有一些包来执行此类操作,但我不知道是哪一个。
在这种情况下不需要 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)
这也会给你相同的结果。
最简单的方法是使用整数除法:
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!
}
希望对您有所帮助