我有一个函数可以从另一个表创建一个熔化的(reshape2包)表,并通过原始名称的转换作为其名称返回它。我需要将它应用于数据帧列表。由于融合函数的“id.var”参数中的变量是原始表的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,但事实并非如此。 在这种情况下,它会打印每个数据框名称,但对于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
这不是理想的结果。
如何使用列表中每个元素的rownames? 另外,我想避免在屏幕上打印表格。
答案 0 :(得分: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)
}
由于我们想要使用与名称相关联的标签,我们还需要做更多的工作:
labs <- sapply(names(tblList),
function(x) substr(x,4,nchar(x)))
res <- mapply(meltfun,tblList,labs,SIMPLIFY=FALSE)
setNames(res,paste0("df",labs)