R- lapply 保留行名

R- lapply preserve rownames

我有一个函数可以从另一个创建融化的(reshape2 包)table,然后 returns 它以原始名称的转换作为其名称。我需要将它应用于数据框列表。由于 melt 函数 "id.var" 参数中的变量是原始 table 的行名,我在保存它们时遇到了问题。

我原来的函数是:

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 的想法将像保留名称一样保留行名,但事实并非如此。 在这种情况下,它会打印每个数据框名称,但对于行名,我得到 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

这不是想要的结果。

我怎样才能同时使用列表中每个元素的行名? 另外我想避免在屏幕上打印 table。

我可以推荐一种替代方法吗?使用 assign<<-,除非在极少数情况下,通常意味着您使用的是非惯用的 R 和

来自R Inferno,第6圈:

If you think you need <<- , think again. If on reflection you still think you need <<- , think again.

设置数据:

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)
}

由于我们要使用与名称关联的标签,因此我们需要做更多的工作:

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

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