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)
我有一个函数可以从另一个创建融化的(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)