如何创建数据迁移矩阵?

How to create a matrix of data migration?

假设我们从这个数据帧开始,下面是生成它的 R 代码:

> data
   ID Period Values Flags
1   1      1      5    X0
2   1      2     10    X1
3   1      3     15    X2
4   1      4     20    X3
5   2      1      0    X0
6   2      2      2    X2
7   2      3      4    XO
8   2      4      6    X1
9   3      1      3    XO
10  3      2      6    XO
11  3      3      9    X2
12  3      4     12    XO

data <- 
  data.frame(
    ID = c(1,1,1,1,2,2,2,2,3,3,3,3),
    Period = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4),
    Values = c(5, 10, 15, 20, 0, 2, 4, 6, 3, 6, 9, 12),
    Flags = c("X0","X1","X2","X3","X0","X2","XO", "X1", "XO","XO","X2","XO")
  )

我正在尝试生成代码,根据用户输入的 2 个句点,显示 ID 的数量(以及 ID 的值)从一个“标志”类别到下一个类别的迁移。因此,例如,如果用户输入期间 1 作为“从”期间,期间 4 作为“到”期间,我们将获得迁移表,如底部图像所示。为了便于说明,我还在图像的右侧包括了 2/3 from/to。

我通常在 Excel 中完成此类分析,这是一个繁琐的多步骤过程,现在正在 R 中尝试。

对此编码有什么建议吗?

以下是创建所需的两个表的函数。

请注意,您的模拟数据集中的 X0 和 XO 存在问题,正如 r2evans 已经建议的那样(我已将所有内容都转换为 X0)。

data <- 
  data.frame(
    ID = c(1,1,1,1,2,2,2,2,3,3,3,3),
    Period = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4),
    Values = c(5, 10, 15, 20, 0, 2, 4, 6, 3, 6, 9, 12),
    Flags = c("X0","X1","X2","X3","X0","X2","X0", "X1", "X0","X0","X2","X0")
  )

generateTable <- function(data){
  df <- data.frame(matrix(NA, ncol=length(unique(data$Flags)), nrow=length(unique(data$Flags))))
  row.names(df) <- unique(data$Flags)
  names(df) <- unique(data$Flags)
  return(df)
}

numbers2migrate <- function(data, from=1, to=4){
  df <- generateTable(data)
  for (i in unique(data$ID)){
    id_from <- as.character(data$Flags[(data$ID == i & data$Period == from)])
    id_to <- as.character(data$Flags[data$ID == i & data$Period == to])
    column <- which(names(df) == id_from)
    row <- which(row.names(df) == id_to)
    df[row, column] <- ifelse(is.na(df[row, column]), 1, df[row, column] + 1)
  }
  return(df)
}

values2migrate <- function(data, from=1, to=4){
  df <- generateTable(data)
  for (i in unique(data$ID)){
    id_from <- as.character(data$Flags[(data$ID == i & data$Period == from)])
    id_to <- as.character(data$Flags[data$ID == i & data$Period == to])
    column <- which(names(df) == id_from)
    row <- which(row.names(df) == id_to)
    
    val <- (data$Values[(data$ID == i & data$Period == from)])
    df[row, column] <- val
  }
  return(df)
}


> numbers2migrate(data, from=1, to=4)
   X0 X1 X2 X3
X0  1 NA NA NA
X1  1 NA NA NA
X2 NA NA NA NA
X3  1 NA NA NA
> values2migrate(data,1,4)
   X0 X1 X2 X3
X0  3 NA NA NA
X1  0 NA NA NA
X2 NA NA NA NA
X3  5 NA NA NA