R - 致力于速度/效率 - 从大文件创建和更新矩阵
R - Working on Speed / Efficiency - Creating + Updating a Matrix from a large file
我将从我的直觉开始 - 我假设有一些方法可以使用 "apply" 来做到这一点,而无需循环遍历我文件中的每个条目,但我无法弄清楚。
我有一个非常大的文件。大约 4,000,000 行,6 列。为了便于讨论,这些列中只有 3 列是相关的。它们是 day
、grade1
和 grade2
我想创建一个包含多个字段的矩阵,使用上面提到的我的 .txt 中的那 3 列。
我想要 day
、grade1Wins
、grade2Wins
、ties
、grade1Score
、grade2Score
、grade1Avg
和 grade2Avg
。这些都是每天的。
所以我的输出矩阵将有 8 列,行数等于天数。
我定义如下。
Grade1Wins
:从 0 开始,每行递增 1,其中 Grade1
> |Grade2|
。
Grade2Wins
:从 0 开始,每行递增 1,其中 |Grade2|
> Grade1
。
ties
:从 0 开始,每行递增 1,其中 Grade1
== |Grade2|
Grade1Score
:原始分值的总和。
Grade2Score
:原始分值的总和。
Grade1Avg :
Grade1Score/ (numRows)
Grade2Avg : Grade2Score
/ (numRows)
我想要这一切作为矩阵。因此,例如,我的数据可能看起来像....(仅显示 2 个相关列的子集)
Day Grade1 Grade2
1 2 -4
1 4 -4
2 10 -1
所以我的输出矩阵是
`day` `grade1wins` `grade2wins` `ties` `grade1score` `grade2score` `grade1avg` `grade2avg`
1 0 1 1 6 -8 2 -4
2 1 0 0 10 -1 10 -1
目前,我通过循环执行此操作。
我的矩阵是预定义的(#cols / #rows 预先确定,有一个全0的空白矩阵等待编辑)。
我遍历制表符分隔的 .txt 文件的每一行。
我确定当前行的日期。这是我的行号。
我从 grade1
和 grade2
.
的行中提取值
#Loop over every single row.
for(i in 1:len)
{
entry = entries[i,]
rowNum = entry$day
if( entry$grade1> abs(entry$grade2) )
{
mat[rowNum, "grade1wins"] = mat[rowNum, "grade1wins"] + 1 ## Increment the counter
} else if( abs(entry$grade2) > entry$grade1 ) {
mat[rowNum, "grade2wins"] = mat[rowNum, "grade2wins"] + 1 ## Increment the counter
} else {
mat[rowNum, "ties"] = mat[rowNum, "ties"] + 1
}
mat[rowNum, "grade1"] = mat[rowNum, "grade1"] + entry$grade1
mat[rowNum, "grade2"] = mat[rowNum, "grade2"] + entry$grade2
} # end loop, we went through every single entry now
mat[, "PosAvg"] = mat[,"PosScore"] / mat[, "NumTweets"]
mat[, "NegAvg"] = mat[,"NegScore"] / mat[, "NumTweets"]
我想有一些方法可以使用 "apply" 来做到这一点,而无需遍历我文件中的每个条目,但我无法弄清楚。
您可以在 data.table
包的帮助下完成此操作。
您可以借助 fread()
函数读取数据集,并将数据集保存到变量中,例如 data2。
现在,您可以通过以下代码应用所需的操作:
test_function <- function(dt){
grade1wins <- length(which(dt$Grade1 > abs(dt$Grade2)))
grade2wins <- length(which(dt$Grade1 < abs(dt$Grade2)))
ties <- nrow(dt) - grade1wins - grade2wins
grade1score <- sum(dt$Grade1)
grade2score <- sum(dt$Grade2)
grade1avg <- mean(dt$Grade1)
grade2avg <- mean(dt$Grade2)
return (list(grade1wins = grade1wins,grade2wins = grade2wins,
ties = ties,grade1score = grade1score,grade2score = grade2score,
grade1avg = grade1avg,grade2avg = grade2avg))
}
> as.matrix(data2[,test_function(.SD),by=Day])
Day grade1wins grade2wins ties grade1score grade2score grade1avg grade2avg
[1,] 1 0 1 1 6 -8 3 -4
[2,] 2 1 0 0 10 -1 10 -1
我将从我的直觉开始 - 我假设有一些方法可以使用 "apply" 来做到这一点,而无需循环遍历我文件中的每个条目,但我无法弄清楚。
我有一个非常大的文件。大约 4,000,000 行,6 列。为了便于讨论,这些列中只有 3 列是相关的。它们是 day
、grade1
和 grade2
我想创建一个包含多个字段的矩阵,使用上面提到的我的 .txt 中的那 3 列。
我想要 day
、grade1Wins
、grade2Wins
、ties
、grade1Score
、grade2Score
、grade1Avg
和 grade2Avg
。这些都是每天的。
所以我的输出矩阵将有 8 列,行数等于天数。
我定义如下。
Grade1Wins
:从 0 开始,每行递增 1,其中 Grade1
> |Grade2|
。
Grade2Wins
:从 0 开始,每行递增 1,其中 |Grade2|
> Grade1
。
ties
:从 0 开始,每行递增 1,其中 Grade1
== |Grade2|
Grade1Score
:原始分值的总和。
Grade2Score
:原始分值的总和。
Grade1Avg :
Grade1Score/ (numRows)
Grade2Avg : Grade2Score
/ (numRows)
我想要这一切作为矩阵。因此,例如,我的数据可能看起来像....(仅显示 2 个相关列的子集)
Day Grade1 Grade2
1 2 -4
1 4 -4
2 10 -1
所以我的输出矩阵是
`day` `grade1wins` `grade2wins` `ties` `grade1score` `grade2score` `grade1avg` `grade2avg`
1 0 1 1 6 -8 2 -4
2 1 0 0 10 -1 10 -1
目前,我通过循环执行此操作。 我的矩阵是预定义的(#cols / #rows 预先确定,有一个全0的空白矩阵等待编辑)。
我遍历制表符分隔的 .txt 文件的每一行。
我确定当前行的日期。这是我的行号。
我从 grade1
和 grade2
.
#Loop over every single row.
for(i in 1:len)
{
entry = entries[i,]
rowNum = entry$day
if( entry$grade1> abs(entry$grade2) )
{
mat[rowNum, "grade1wins"] = mat[rowNum, "grade1wins"] + 1 ## Increment the counter
} else if( abs(entry$grade2) > entry$grade1 ) {
mat[rowNum, "grade2wins"] = mat[rowNum, "grade2wins"] + 1 ## Increment the counter
} else {
mat[rowNum, "ties"] = mat[rowNum, "ties"] + 1
}
mat[rowNum, "grade1"] = mat[rowNum, "grade1"] + entry$grade1
mat[rowNum, "grade2"] = mat[rowNum, "grade2"] + entry$grade2
} # end loop, we went through every single entry now
mat[, "PosAvg"] = mat[,"PosScore"] / mat[, "NumTweets"]
mat[, "NegAvg"] = mat[,"NegScore"] / mat[, "NumTweets"]
我想有一些方法可以使用 "apply" 来做到这一点,而无需遍历我文件中的每个条目,但我无法弄清楚。
您可以在 data.table
包的帮助下完成此操作。
您可以借助 fread()
函数读取数据集,并将数据集保存到变量中,例如 data2。
现在,您可以通过以下代码应用所需的操作:
test_function <- function(dt){
grade1wins <- length(which(dt$Grade1 > abs(dt$Grade2)))
grade2wins <- length(which(dt$Grade1 < abs(dt$Grade2)))
ties <- nrow(dt) - grade1wins - grade2wins
grade1score <- sum(dt$Grade1)
grade2score <- sum(dt$Grade2)
grade1avg <- mean(dt$Grade1)
grade2avg <- mean(dt$Grade2)
return (list(grade1wins = grade1wins,grade2wins = grade2wins,
ties = ties,grade1score = grade1score,grade2score = grade2score,
grade1avg = grade1avg,grade2avg = grade2avg))
}
> as.matrix(data2[,test_function(.SD),by=Day])
Day grade1wins grade2wins ties grade1score grade2score grade1avg grade2avg
[1,] 1 0 1 1 6 -8 3 -4
[2,] 2 1 0 0 10 -1 10 -1