-2

アドバイスやヒントをお寄せいただきありがとうございます。私はデータフレームを扱っています。簡略化されたコーディングは次のとおりです。

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) 

`

警告メッセージ: In is.na(x) : is.na() applied to non-(list or vector) of type 'NULL'

出力が正しくありません。デバッグを試みたところ、競合が行 1) と 2) にある可能性があることがわかりました。ただし、 f(name) を試してみると、まったく問題なく、出力は正しいです。問題はラップリーにあると思います。しばらく検索しましたが、ポイントに到達できませんでした。何か案は?どうもありがとう!

データの構造

ありがとうジョラン。もう一度確認したところ、問題は私が説明したものではない可能性があることがわかりました. 次のように完全なコードを生成し、コピーして貼り付けてエラーを確認できます。

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) は私が望む行列を正確に生成します。再度、感謝します。

4

1 に答える 1

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あなたがに着くとき

y<-dataset[[deparse(substitute(name))]]

内部では、 namedlapplyの要素を探していますが、要素がないため、にバインドされています。datasetX[[1L]]yNULL

それを機能させる方法

これに対処する最も簡単な方法は、おそらくf文字列を操作しnames(list_names)てlapplyに渡すことです。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、およびを含むすべてのさまざまな変数など、さまざまな目的で使用されないようにすることも検討してください。 name

于 2013-01-19T07:48:49.807 に答える