R从长到宽重塑数据,反之亦然

时间:2012-03-07 15:31:01

标签: r long-integer reshape

我为cast和melt编写了两个包装器函数,以便从长时间内获取数据 宽泛的形式,反之亦然。但是,我仍然在努力解决这个问题 reshape_wide将数据从长格式转换为宽格式。

以下是我的示例函数以及运行它的代码。我创建了一个虚拟的data.frame 格式,我使用我的reshape_long函数重塑为长格式,然后使用我的reshape_wide函数将其转换回原始的宽格式。然而,重塑失败的原因我无法理解。似乎dcast中使用的公式是错误的。

reshape_long <- function(data, identifiers) {
    data_long <- melt(data, id.vars = identifiers, 
                            variable.name="name", value.name="value")
    data_long$value <- as.numeric(data_long$value)
    data_long <- data_long[!is.na(data_long$value), ]
    return(data_long)
}

reshape_wide <- function(data, identifiers, name) {
    if(is.null(identifiers)) {
        formula_wide <- as.formula(paste(paste(identifiers,collapse="+"), 
                                   "series ~ ", name))      
    } else {
        formula_wide <- as.formula(paste(paste(identifiers,collapse="+"), 
                                   "+ series ~ ", name))
    }
    series <- ave(1:nrow(data), data$name, FUN=function(x) { seq.int(along=x) }) 
    data <- cbind(data, series) 
    data_wide <- dcast(data, formula_wide, value.var="value")
    data_wide <- data_wide[,!(names(data_wide) %in% "series")]
    return(data_wide)
}


data <- data.frame(ID = rep("K", 6), Type = c(rep("A", 3), rep("B", 3)),
                   X = c(NA,NA,1,2,3,4), Y = 5:10, Z = c(NA,11,12,NA,14,NA))
data <- reshape_long(data, identifiers = c("ID", "Type"))
data
reshape_wide(data, identifiers = c("ID", "Type"), name="name")

当我运行上面的代码时,这是我的R输出的链接:

http://pastebin.com/ej8F9GnL

错误的是,列B中出现5次而不是3次。 你得到相同的data.frame吗?

这是sessionInfo()

的R输出
> sessionInfo()
R version 2.14.0 (2011-10-31)
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit)

locale:
[1] C

attached base packages:
[1] grid      stats     graphics  grDevices utils     datasets  methods  
[8] base     

other attached packages:
 [1] reshape2_1.2.1       outliers_0.14        lme4_0.999375-42    
 [4] Matrix_1.0-1         gregmisc_2.1.2       gplots_2.10.1       
 [7] KernSmooth_2.23-7    caTools_1.12         bitops_1.0-4.1      
[10] gtools_2.6.2         gmodels_2.15.1       gdata_2.8.2         
[13] lattice_0.20-0       dataframes2xls_0.4.5 RankProd_2.26.0     
[16] R.utils_1.9.3        R.oo_1.8.3           R.methodsS3_1.2.1   
[19] xlsx_0.3.0           xlsxjars_0.3.0       rJava_0.9-2         
[22] rj_1.0.0-3          

loaded via a namespace (and not attached):
[1] MASS_7.3-16   nlme_3.1-102  plyr_1.6      rj.gd_1.0.0-1 stats4_2.14.0
[6] stringr_0.5   tools_2.14.0 

2 个答案:

答案 0 :(得分:0)

问题可能在这里:

series <- ave(1:nrow(data), data$name, FUN=function(x) { seq.int(along=x) }) 

应该摆脱使用&#34; $&#34;的习惯。在函数中,因为它不解释传递的值。使用&#34; [[&#34;并且不引用这个论点:

series <- ave(1:nrow(data), data[[name]], FUN=function(x) { seq.int(along=x) }) 

在此示例中,它不会产生任何影响,因为name ==&#34; name&#34;,但如果您尝试将其与name的任何其他值一起使用,则会失败。

答案 1 :(得分:0)

该示例不起作用: 因为ID和类型不形成主键 (即,因为有几行具有相同的id和类型), 当数据以高格式放入时,您不再知道 如果两个值来自同一行。

另外,我不确定您要对series列做什么, 但它似乎不起作用。

library(reshape2)
d <- data.frame(
  ID = rep("K", 6), 
  Type = c(rep("A", 3), rep("B", 3)),
  X = c(NA,NA,1,2,3,4), 
  Y = 5:10, 
  Z = c(NA,11,12,NA,14,NA)
)
d$row <- seq_len(nrow(d))  # (row,ID,Type) is now a primary key
d
d1 <- reshape_long(d, identifiers = c("row", "ID", "Type"))
d1
dcast(d1, row + ID + Type ~ name) # Probably what you want
reshape_wide(d1, identifiers = c("row", "ID", "Type"), name="name")