非常感谢任何建议或提示。 我正在使用数据框。简化编码如下: `
f<-funtion(name){
x<-tapply(name$a,list(name$b,name$c),sum)
1) y<-dataset[[deparse(substitute(name))]]
#where dataset is an already existed list object with names the same as the
#function argument. I would like to avoid inputting two arguments.
z<-vector("list",n) #where n is also defined already
2) for (i in 1:n){z[[i]]<-x[y[[i]],i]}
...
}
lapply(list_names,f)
`
警告信息是: 在is.na(x)中:is.na()应用于'NULL'类型的非(列表或向量)
并且输出不正确。我试过调试,发现冲突可能在第1)和第2行。但是,当我尝试f(名称)时,它非常精细且输出正确。我想问题是在lapply,我搜索了一段时间,但无法达到目的。有任何想法吗?非常感谢!
谢谢Joran。再次检查我发现问题可能不在我所描述的内容中。我按如下方式生成完整代码,您可以复制粘贴以查看错误。
n<-4
name1<-data.frame(a=rep(0.1,20),b=rep(1:10,each=2),c=rep(1:n,each=5),
d=rep(c("a1","a2","a3","a4","a5","a6","a7","a8","a9","a91"),each=2))
name2<-data.frame(a=rep(0.2,20),b=rep(1:10,each=2),c=rep(1:n,each=5),
d=rep(c("a1","a2","a3","a4","a5","a6","a7","a8","a9","a91"),each=2))
name3<-data.frame(a=rep(0.3,20),b=rep(1:10,each=2),c=rep(1:n,each=5),
d=rep(c("a1","a2","a3","a4","a5","a6","a7","a8","a9","a91"),each=2))
#d is the name for the observations. d corresponds to b.
dataset<-vector("list",3)
names(dataset)<-c("name1","name2","name3")
dataset[[1]]<-list(c(1,2),c(1,2,3,4),c(1,2,3,4,5,10),c(4,5,8))
dataset[[2]]<-list(c(1,2,3,5),c(1,2),c(1,2,10),c(2,3,4,5,8,10))
dataset[[3]]<-list(c(3,5,8,10),c(1,2,5,7),c(1,2,3,4,5),c(2,3,4,6,9))
f<-function(name){
x<-tapply(name$a,list(name$b,name$c),sum)
rownames(x)<-sort(unique(name$d)) #the row names for
y<-dataset[[deparse(substitute(name))]]
z<-vector("list",n)
for (i in 1:n){
z[[i]]<-x[y[[i]],i]}
nn<-length(unique(unlist(sapply(z,names)))) # the number of names appeared
names_<-sort(unique(unlist(sapply(z,names)))) # the names appeared add to the matrix
# below
m<-matrix(,nrow=nn,ncol=n);rownames(m)<-names_
index<-vector("list",n)
for (i in 1:n){
index[[i]]<-match(names(z[[i]]),names_)
m[index[[i]],i]<-z[[i]]
}
return(m)
}
list_names<-vector("list",3)
list_names[[1]]<-name1;list_names[[2]]<-name2;list_names[[3]]<-name3
names(list_names)<-c("name1","name2","name3")
lapply(list_names,f)
f(name1)
lapply(list_names,f)会失败,但是f(name1)会产生我想要的矩阵。再次感谢。
答案 0 :(得分:5)
问题是调用堆栈在两种情况下看起来都不一样。在lapply
中,它看起来像
[[1]]
lapply(list_names, f) # lapply(X = list_names, FUN = f)
[[2]]
FUN(X[[1L]], ...)
在正在评估的表达式中,f
被称为FUN
,其参数name
被称为X[[1L]]
。
直接拨打f
时,堆栈只是
[[1]]
f(name1) # f(name = name1)
通常这没关系,但是substitute
确实如此,因为substitute
关心函数参数的名称,而不是它的值。当你到达 p>
y<-dataset[[deparse(substitute(name))]]
在lapply
内,它正在寻找名为dataset
的{{1}}中的元素,而没有一个元素,因此X[[1L]]
绑定到y
。
处理此问题的最简单方法可能是让NULL
对字符串进行操作并将f
传递给lapply。通过将names(list_names)
的开头更改为
f
并将f<-function(name){
passed.name <- name
name <- list_names[[name]]
x<-tapply(name$a,list(name$b,name$c),sum)
rownames(x)<-sort(unique(name$d)) #the row names for
y<-dataset[[passed.name]]
# the rest of f...
更改为lapply(list_names, f)
。这应该通过几乎最小的修改为您提供所需的内容,但您也可以考虑重命名一些变量,因此单词lapply(names(list_names),f)
不会用于许多不同的东西 - 函数name
, names
的参数,以及包含f
的所有各种变量。