我为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输出的链接:
错误的是,列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
答案 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")