2012-03-07 5 views
0

Я написал две функции обертки для литья и расплава, чтобы донести мои данные от до широкой формы и наоборот. Тем не менее, я все еще борюсь с функцией reshape_wide, которая приносит данные из длинной формы в широкую форму.R изменить данные от длинного до широкого и наоборот

Вот мои примеры функций плюс код для его запуска. Я создал фиктивный 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?

Вот выход R из sessionInfo()

> 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

Это работает на моей машине. Какую версию пакета reshape вы используете? Возможно, добавьте результаты 'sessionInfo()' к вашему вопросу. – Andrie

ответ

0

пример не может работать: , так как 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") 
+0

Он работает в настоящее время. Это была проблема отсутствия «первичного ключа»! Отлично. Большое спасибо! – user969113

0

Проблема может быть здесь:

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

Если выйти из привычку использовать "$" в функциях, так как оно не интерпретирует переданные значения. Используйте «[[» и не процитировать аргумент:

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

В данном примере это не будет иметь значение, потому что name == «имя», но если вы попытаетесь использовать его с любым другим значением для name это потерпит неудачу.

+0

Оба способа использования ave дают точно такой же результат. Я не думаю, что это проблема. Я думаю, что я использую функцию dcast. Тем не менее, преобразование из широких -> длинных -> широких работает, когда данные сбалансированы! Попробуйте со следующими данными.frame: data <- data.frame (ID = rep («K», 6), Type = c (Rep ("А", 3), Rep ("Б", 3)), \t \t \t \t Х = 1: 6, Y = 7:12, Z = 13:18) – user969113

Смежные вопросы