r - 为变量中的每个唯一元素创建一个转换矩阵

标签 r database matrix data-manipulation

我在创建转换矩阵时遇到问题,该矩阵位于我正在处理的数据集下方,

Name     Rating   ID   DATE(YYYYmmdd)   
@0CC        1   71476   20000704    
@0CC        1   71476   20001204    
@0RM        1   73565   20000919    
@0RM        2   49960   20000131    
@0RM        1   44457   20001214    
@0RM        1   59451   20001023    
@0TL        2   73862   20001212    
@0TL        3   19824   20000929    
@0TL        1   70970   20001211    
@0TL        3   48061   20000627          
@0TL        1   48061   20001227    
@1AJ        1   58875   20001214    
@1AJ        3   56014   20001214    
@1AJ        3   47340   20001214    
@1AJ        3   19813   20001214    
@1AL        1   44416   20000517    
@1AL        4   59184   20000801    
@1AL        3   59184   20000413    
@1AL        4   72832   20001127    
@1AL        1   52718   20000621    
@1AL        2   59184   20000707    
@1AL        3   73568   20001130    
@1AL        3   72832   20001211    
@1AL        3   44416   20000303    

我想做的是对于每个唯一的名字,我想比较 ID,如果 ID 匹配,我会查看日期,将较晚的日期与较早的日期进行比较,如果评级相似,我会忽略,但如果评级不同,我想计算移动次数。

例如,在前两行中,查看 Name @OCC,ID 变量匹配并查看评级,它们相似,那么我不将其添加到计数中。但是,查看@1AL,ID 变量匹配三次,查看发生的日期,有 3 个日期 20000413、20000707 和 20000801,评级分别为 3,2 和 4。随着评分再次从 3 变为 2 再变为 4,我想将其记录在以下格式的转换矩阵中。

 From   1 2 3 4 5 (to)
  1
  2           1 
  3       1
  4
  5

对于数据管理这件事还很陌生,这就是我所拥有的,

for(i in unique(dataset$Name)
if dataset[,3]=dataset[,3]

我不认为第二行是正确的。我真的真的被困住了,很感激我能得到的任何建议。

最佳答案

这花了一些时间,但我想我找到了解决您问题的方法:

转换成data.table

install.packages("data.table") #if not installed already
require(data.table)
### DT: your data.frame
### e.g. copy and 
#DT <- read.table("clipboard",header = T)
DT <- as.data.table(DT) # convert into data.table
setkey(DT, Name, DATE)
#this shows some temporary result:
DT[, print(Rating), by = list(Name, ID)]
  # [1] 1 1
  # [1] 1
  # [1] 2
  # [1] 1
  # [1] 1
  # [1] 2
  # [1] 3
  # [1] 1
  # [1] 3 1
  # [1] 1
  # [1] 3
  # [1] 3
  # [1] 3
  # [1] 1 3
  # [1] 4 3 2
  # [1] 4 3
  # [1] 1
  # [1] 3

一个问题是 data.table 不会为每个子集返回一个向量(据我所知)。所以解决方案是将单个数字转换为更长的数字,然后再将它们转换回来。

获取评分

setVal <- function(vec){
  res <- 0
  for (i in 1:length(vec)){
    res <- res + vec[i] * 10^(length(vec)-i)
  }
  return(as.integer(res))
}
#save above shown result in vector.
DT <- DT[, R:=setVal(Rating), by = list(Name, ID)]
DT #the result is not as desired because e.g. 324 occurs 3 times (at each row which leads to 324), 11 occurs 2 times (at both rows contributing to 11).
  # Name Rating    ID DATE.YYYYmmdd.   R
  # 1: @0CC      1 71476       20000704  11
  # 2: @0CC      1 71476       20001204  11
  # 3: @0RM      2 49960       20000131   2
  # 4: @0RM      1 73565       20000919   1
  # 5: @0RM      1 59451       20001023   1
  # 6: @0RM      1 44457       20001214   1
  # 7: @0TL      3 48061       20000627  31
  # 8: @0TL      3 19824       20000929   3
  # 9: @0TL      1 70970       20001211   1
  # 10: @0TL      2 73862       20001212   2
  # 11: @0TL      1 48061       20001227  31
  # 12: @1AJ      1 58875       20001214   1
  # 13: @1AJ      3 56014       20001214   3
  # 14: @1AJ      3 47340       20001214   3
  # 15: @1AJ      3 19813       20001214   3
  # 16: @1AL      3 44416       20000303  31
  # 17: @1AL      3 59184       20000413 324
  # 18: @1AL      1 44416       20000517  31
  # 19: @1AL      1 52718       20000621   1
  # 20: @1AL      2 59184       20000707 324
  # 21: @1AL      4 59184       20000801 324
  # 22: @1AL      4 72832       20001127  43
  # 23: @1AL      3 73568       20001130   3
  # 24: @1AL      3 72832       20001211  43
#The result has to be filtered by unique pairs of Name and ID.
R <- DT[,unique(R), by = list(Name, ID)]$V1
#[1]  11   2   1   1   1  31   3   1   2   1   3   3   3  31 324   1  43   3

将结果转换为转换矩阵

可能有一些更简单的方法可以将 R 转换回个位数,计算值并将它们放入矩阵中,但这就是我的想法:

TransitionMatrix <- function(col, ncol = 5){
  intoMat <- function(Mat, vec){
    if(length(vec)>1){
      for (i in 1:(length(vec)-1)){
        if (vec[i] != vec[i+1]){
          Mat[vec[i], vec[i+1]] <- Mat[vec[i], vec[i+1]] + 1
        }
      }
    }
    return(Mat)
  }
  Mat <- matrix(0, ncol = ncol, nrow = ncol)
  for (j in 1:length(col)){
    L <- nchar(as.character(j))
    if(L>1){
      values <- as.numeric(unlist(strsplit(as.character(col[j]),"")))
      Mat <- intoMat(Mat, values)
    }
  }
  return(Mat)
}

TransitionMatrix(R, 5)
  #      [,1] [,2] [,3] [,4] [,5]
  # [1,]    0    0    2    0    0
  # [2,]    0    0    0    0    0
  # [3,]    2    3    0    0    0
  # [4,]    0    0    5    0    0
  # [5,]    0    0    0    0    0

此解决方案的一个局限性是评分高于 9 且有 2 个数字。

关于r - 为变量中的每个唯一元素创建一个转换矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38542639/

相关文章:

algorithm - Scala中nxm和mxp矩阵的乘法算法

在 R 中,如果满足条件,则将值替换为新值,如果不满足,则保持值相同

PHP 驱动的详尽统计数据 - 服务器端文本文件或 MySQL 表?

php - 如何连接两个数据库表并从连接表中返回最低价格

mysql - 现代 Web 应用程序如何对大量快速变化的数据实现缓存和数据持久化?

java - 如何实现一种方法来查找 5x5 矩阵中每行和每列的最大元素?

matlab - 在 MATLAB 中置换矩阵的列

r - 调整 font.lab 以在 plotmath 表达式中加粗?

r - 水平图中的一侧边距

r - 在 R 中,如何将矩阵市场格式的稀疏矩阵加载到 dgCMatrix 中?