2016-07-11 3 views
0

У меня есть функция, которая создает таблицу расплавленного (reshape2 package) из другого и возвращает ее с преобразованием исходного имени в качестве его имени. Мне нужно применить его к списку данных. Поскольку переменные, находящиеся в параметре «id.var» функции расплава, являются именами ростов оригинальной таблицы, у меня возникают проблемы с их сохранением.R- lapply сохранить rownames

Моя оригинальная функция:

creaMelts<-function(tbl){ 
    library(reshape2) 
    texto<-deparse(substitute(tbl)) 
    tbl2<-melt(tbl, id.vars=rownames(tbl)) 
    texto2<-substr(texto,4,nchar(texto)) 
    colnames(tbl2)<-c('userId','movieId', texto2) 
    tblName<<-paste0('df', texto2) 
    assign(tblName, tbl2) 
    return(assign(tblName, tbl2, envir = .GlobalEnv)) 
} 

Пару кадров данных:

tbl1<-data.frame(a=seq(1,2,1), 'X1'=seq(2,3,1), 'X2'=seq(3,4,1)) 
rownames(tbl1)<-c('X1', 'X2') 
tbl2<-data.frame(a=seq(1,2,1), 'X1'=seq(3,4,1), 'X2'=seq(4,5,1)) 
rownames(tbl2)<-c('X1', 'X2') 

Так что, если я бегу:

creaMelts(tbl1) 

А потом я прошу df1, я получаю желаемый результат:

userId movieId 1 NA 
     2  3 a 1 
     3  4 a 2 

Поскольку мне нужно сделать это Ф.О. список:

lista=list(tbl1=tbl1,tbl2=tbl2) 

Я писал:

lapply(seq_along(lista),function(tbl,n,rn,i){ 
    library(reshape2) 
    texto<-n[[i]] 
    print(texto) 
    print(rn[[i]]) 
    tbl2<-melt(tbl, id.vars=rn[[i]]) 
    texto2<-substr(texto,4,nchar(texto)) 
    colnames(tbl2)<-c('userId','movieId', texto2) 
    tblName<-paste0('df', texto2) 
    assign(tblName, tbl2) 
    return(assign(tblName, tbl2, envir = .GlobalEnv)) 
}, tbl=lista,n=names(lista), rn=rownames(lista)) 

Следуя идее, что добавление параметра в lapply сохранит rownames, как это делает с именами, но это не так. В этом случае он печатает каждое имя фрейма данных, но для имен ростов я получаю NULL.

Если я спрошу сейчас df1, я получаю

userId movieId 1 
     a  1 tbl1 
     a  2 tbl1 
     X1  2 tbl1 
     X1  3 tbl1 
     X2  3 tbl1 
     X2  4 tbl1 
     a  1 tbl2 
     a  2 tbl2 
     X1  3 tbl2 
     X1  4 tbl2 
     X2  4 tbl2 
     X2  5 tbl2 

Который не является желаемым результатом.

Как я могу использовать имена ростов для каждого элемента списка? Также я хотел бы избежать печати таблицы на экране.

+0

частое использование '<< -' и 'назначить()' предлагает вы используете R без идиоматически ... –

ответ

2

Могу ли я предложить альтернативный подход? Использование assign и <<-, за исключением очень редких случаях, как правило, означает, что вы используете не-идиоматических R и

Из R Inferno, Круг 6:

Если вы думаете, что вам нужно <<-, подумайте еще раз. Если по размышлению вы все еще думаете, что вам нужно <<-, подумайте еще раз.

Настройка данных:

tbl1 <- data.frame(a=seq(1,2,1), 'X1'=seq(2,3,1), 'X2'=seq(3,4,1)) 
rownames(tbl1)<-c('X1', 'X2') 
tbl2 <- data.frame(a=seq(1,2,1), 'X1'=seq(3,4,1), 'X2'=seq(4,5,1)) 
rownames(tbl2)<-c('X1', 'X2') 

Положите ваши таблицы в списке (первый шаг к делать что-то ощутимое с коллекцией предметов в R):

tblList <- list(tbl1=tbl1,tbl2=tbl2) 

Теперь написать свой функции:

meltfun <- function(x,lab=1) { 
    z <- reshape2::melt(x,id.vars=rownames(x)) 
    colnames(z) <- c('userId','movieId', lab, "value") 
    return(z) 
} 

Поскольку мы хотим использовать этикетки associat ред с именами, мы должны сделать немного больше работы:

labs <- sapply(names(tblList), 
      function(x) substr(x,4,nchar(x))) 

res <- mapply(meltfun,tblList,labs,SIMPLIFY=FALSE) 
setNames(res,paste0("df",labs) 
+0

спасибо. Я думаю, что это решение. Есть ли способ избежать печати в setNames? – GabyLP

+0

невидимый (setNames (...)) – GabyLP

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