R-致力于提高速度/效率-创造+;从大文件更新矩阵

R-致力于提高速度/效率-创造+;从大文件更新矩阵,r,performance,matrix,apply,R,Performance,Matrix,Apply,我从我的直觉开始——我认为有某种方法可以使用“apply”来实现这一点,而不必遍历文件中的每个条目,但我无法理解 我有一个很大的文件。大约4000000行,6列。为了便于讨论,这些专栏中只有3篇是相关的。它们是day、grade1和grade2 我想使用上面提到的my.txt中的3列创建一个包含多个字段的矩阵 我想要day,grade1Wins,grade2Wins,ties,grade1Score,grade2Score,grade1Avg和grade2Avg。这些都是每天的 因此,我的输出矩

我从我的直觉开始——我认为有某种方法可以使用“apply”来实现这一点,而不必遍历文件中的每个条目,但我无法理解

我有一个很大的文件。大约4000000行,6列。为了便于讨论,这些专栏中只有3篇是相关的。它们是
day
grade1
grade2

我想使用上面提到的my.txt中的3列创建一个包含多个字段的矩阵

我想要
day
grade1Wins
grade2Wins
ties
grade1Score
grade2Score
grade1Avg
grade2Avg
。这些都是每天的

因此,我的输出矩阵将有这8列,行数等于存在的天数

我将这些定义如下

Grade1Wins
:从0开始,每行
Grade1
| Grade2
递增1。
Grade2Wins
:从0开始,在
| Grade2 |
Grade1
中每行递增1。
ties
:从0开始,在
Grade1
==
| Grade2 |

Grade1Score
:原始分数值的总和。
Grade2Score
:原始分数值的总和

Grade1Avg:
Grade1Score
/(numRows)
Grade2Avg:
Grade2Score
/(numRows)

我希望这一切都成为一个矩阵。例如,我的数据可能看起来像……(子集仅显示2个相关列)

所以我的输出矩阵是

`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/#行是预先确定的,有一个满是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"]

我假设有某种方法可以使用“应用”来实现这一点,而不必在我的文件中的每个条目上循环,但我无法找到它。

您可以借助
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

test_函数虽然我可能明天才能尝试,但这是一个很好的解决方案。我可以问一个关于by=天的后续问题吗?我的一些数据集(而不是DayNumber)具有posix格式YYYY-MM-DD HH:MM:SS的时间戳。每天仍然可以按天排序吗?所以,如果我有一个文件,比如说,一月,我会得到31行,每行对应不同的一天?实际上,我已经计算出来了(如.POSIXct(day,format=“%Y-%m-%d”)),但是我还有另外两个问题关于你的解决方案在做什么。那到底是什么,SD?此外,我所有的矩阵值都被引用。添加quotes=FALSE和stringsAsFactors=FALSE并不能修复它。知道发生了什么吗?@Jibril就.SD而言,在这种情况下,它是每天形成的每个组的data2数据的子集。换句话说,它类似于“根据不同的日期值拆分整个数据集”,然后逐个选择每个拆分的数据集。有关更多详细信息,请参阅第二个问题的
?data.table
,因为矩阵中只能有一种类型的元素,所以这些值都是引用的。它可以是向量、数字、字符等等。由于POSIXct更像是一种字符表示法,所以所有元素都转换为某种字符表示法,并生成引号。真漂亮!我决定熬夜并尝试一下,结果效果很好!这段代码在一个多小时前就完成了,现在只需几秒钟。非常感谢你!
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