1

我正在使用的数据集在 Excel 中。它显示了可用性前 26 周的产品销售量和收入。

每行数据代表一个产品。假设有 50 个。
第二个标题行基本上可以用 rep(("Units","Revenue"),26) 在第一个标题行中的每个 ("Units","Revenue") 对上方是一对合并的单元格,采用序列“第 1 周”、“第 2 周”......“第 26 周”。

我基本上想将数据集从 50 行转换为 50*26 = 1300 行,4 列(产品、周、单位、销售额)。

我已经看到了如何处理两个行标题以及如何使用 melt 函数重塑数据,但我不确定我是否看到任何表明将两者结合起来的最佳实践,尤其是在这样的情况下,两个标题行包含重塑数据所需的关键信息。

4

2 回答 2

1

合并单元格可能会产生什么样的 csv 文件有点模棱两可,但假设您首先需要在前两行中readLines使用 using读取的此类单元格数量是其两倍sep=",",那么:

gsub( " ", "", paste( rep( row1[row1 > ""], each=2), c("Units","Revenue"), sep="_") )

对于任何炙手可热的版主:是的,我知道仅代码的答案已被弃用,但我认为它们对于回答代码和数据不足的问题应该是可以接受的。

于 2014-04-23T06:37:15.587 回答
1

我曾多次遇到同样的问题,过去曾在 reshape2 中使用过 melt。但这里有一个函数,它需要多行标题以及多列:

PivReady <- function(data,label_rows,label_columns){
  c<-nrow(data)
  d<-ncol(data)
  pivRdata <- data.frame(matrix(ncol = (label_columns+label_rows+1), nrow = ((c-label_rows)*(d-label_columns))))
    for(i in 1:label_columns){
      pivRdata[,i]<-rep(data[(label_rows+1):c,i],each=(d-label_columns)) 
      }
  trowlabels<-t(data[1:label_rows,(label_columns+1):d])
  pivRdata[,(label_columns+1):(label_columns+label_rows)]<-do.call(rbind, replicate(((c-label_rows)*(d-label_columns))/(d-label_columns), trowlabels, simplify=FALSE))
  datatrans<-t(data[(label_rows+1):c,(label_columns+1):d])
  datatrans<-as.vector(datatrans)
  pivRdata[,(label_columns+label_rows+1)]<-as.data.frame(datatrans)
  names <- data.frame(matrix(ncol = (label_columns+label_rows+1), nrow = 1))
  names[1,1:label_columns]<-as.matrix(data[label_rows,1:label_columns])
  names[1,(label_columns+1):(label_columns+label_rows)]<-paste("Category",1:label_rows,sep="")
  names[1,(label_columns+label_rows+1)]<-"Value"
  names(pivRdata)<-names
  return(pivRdata)
}

是的,我知道这段代码不是很漂亮,但是如果您使用 headers=FALSE 导入数据,然后在上面的函数中指定数据具有例如 2 列标签(最左边的列)和 3 行标题,那么这个工作得很好。

例如。

long_data <- PivReady(wide_data,3,2)
于 2015-02-15T17:33:40.860 回答