2011-11-10 15 views
6

はどういうわけか、時々、私はこのような状態で終わるよ:xとget( "x")の間に奇妙な違いがありますか?

> x 
[1] 1 2 3 
> get("x") 
Error in get("x") : object 'x' not found 
> x 
[1] 1 2 3 

私は確実にそれを再現することはできません。私のCコードでは、どのようなことが間違っていますか?プロンプトでxと入力すると、なぜそれが見つかるのですが、get("x")ではありませんか?内部的にはxget("x")の違いは何ですか?

多くのヒントがあります。私はR 2.14.0以降これを見てきましたが、私のCコードも変更されています。それを実行するための再現性の例

// test.c 
#include <R.h> 
#include <Rdefines.h> 

SEXP test(SEXP df) 
{ 
    SEXP levels, s; 
    int j; 

    levels = getAttrib(VECTOR_ELT(df,0), R_LevelsSymbol); 
    Rprintf("levels %u, type %d, length %d, truelength %d\n", 
      levels,TYPEOF(levels),LENGTH(levels),TRUELENGTH(levels)); 

    for (j=0; j<length(levels); j++) { 
     s = STRING_ELT(levels,j); 
     Rprintf("%d %d %s %u %d %d\n", length(levels), TYPEOF(s), 
         CHAR(s), s, LENGTH(s), TRUELENGTH(s)); 
     SET_TRUELENGTH(s,1); // clobbers the 65, but why 65 ("A") there? 
     Rprintf("%d %d %s %u %d %d\n", length(levels), TYPEOF(s), 
         CHAR(s), s, LENGTH(s), TRUELENGTH(s)); 
    } 
    return(R_NilValue); 
} 

と::

EDIT

R --vanilla 

system("R CMD SHLIB -otest.so test.c") 
dyn.load("test.so") 

if (FALSE) A  # needed for error to occur (!) 

DF <- data.frame(a = c("A", "Z"), b = 1:4) 
print(DF) 
.Call("test",DF) 
print(DF) 

A = data.frame() 
for (i in 1:100) { 
    cat(i,"") 
    assign(paste("v",i,sep=""),i) 
    get("A") 
} 

出力私が取得:

$ R --vanilla  
R version 2.14.0 (2011-10-31) 
# [snip header] 
> system("R CMD SHLIB -otest.so test.c") 
gcc -std=gnu99 -I/usr/share/R/include  -fpic -std=c99 -O6 -Wall -Wno-unused -pedantic -c test.c -o test.o 
gcc -std=gnu99 -shared -o test.so test.o -otest.so -L/usr/lib/R/lib -lR 
> dyn.load("test.so") 
> 
> if (FALSE) A  # needed for error to occur (!) 
> 
> DF <- data.frame(a = c("A", "Z"), b = 1:4) 
> print(DF) 
    a b 
1 A 1 
2 Z 2 
3 A 3 
4 Z 4 
> .Call("test",DF) 
levels 151395176, type 16, length 2, truelength 0 
2 9 A 149596512 1 65 # why this 65 here? 
2 9 A 149596512 1 1 
2 9 Z 149596320 1 0 
2 9 Z 149596320 1 1 
NULL 
> print(DF) 
    a b 
1 A 1 
2 Z 2 
3 A 3 
4 Z 4 
> 
> A = data.frame() 
> for (i in 1:100) { 
+  cat(i,"") 
+  assign(paste("v",i,sep=""),i) 
+  get("A") 
+ } 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Error in get("A") : object 'A' not found 
> 
> sessionInfo() 
R version 2.14.0 (2011-10-31) 
Platform: i686-pc-linux-gnu (32-bit) 

locale: 
[1] LC_CTYPE=en_GB.UTF-8  LC_NUMERIC=C    
[3] LC_TIME=en_GB.UTF-8  LC_COLLATE=en_GB.UTF-8  
[5] LC_MONETARY=en_GB.UTF-8 LC_MESSAGES=en_GB.UTF-8 
[7] LC_PAPER=C     LC_NAME=C     
[9] LC_ADDRESS=C    LC_TELEPHONE=C    
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C  

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  
> 

任意のアイデア? if (FALSE) A行がコメントアウトされていれば正常に動作します。繰り返しテストを行うには、Rを毎回新しく開始する必要があります。

+0

あなたは '私のCコードもtoo'を変更された上で手の込んだことができます。私はCに精通していませんが、間違いなくCコードを投稿し、@Dirk Eddelbuettelが来るのを待ってください。ところで、私はこの振る舞いを再現することはできません。 – aL3xa

+0

@ aL3xaお待ちしております。 –

+1

あなたのコードを公開することははるかに重要です。 =) – aL3xa

答えて

6

これは実際に私のCコードであることが判明しました。私はTRUELENGTHが時々Rで使われているのを知っていましたが、私はCHARSXPについて考えませんでした。変数名がある文字値と同じ場合、CHARSXPのTRUELENGTHはRによって内部ハッシュ値を保持するために使用されます(main/envir.cを参照)。 CHARSXPの私のSET_TRUELENGTHがハッシュを壊していました。これを説明するSimon Urbanekに感謝し、コメントのヒントやアイデアに感謝します。 CHARSXPのTRUELENGTHを参照するにはCのコードがどこにある

$ R --vanilla 
R version 2.14.0 (2011-10-31) 

> system("R CMD SHLIB -otest.so test.c") 
> dyn.load("test.so") 
> truelength = function(x)invisible(.Call("truelength",x)) 
> 
> truelength("A") 
'A' has length 1 and truelength 0 
> truelength("ABC") 
'ABC' has length 3 and truelength 0 
> A=123 
> truelength("A") 
'A' has length 1 and truelength 65 # 65 is the HASHPRI, for bound variable A 
> truelength("ABC") 
'ABC' has length 3 and truelength 0 # no variable ABC so truelength unused 
> ABC=456 
> truelength("ABC") 
'ABC' has length 3 and truelength 17763 # now ABC symbol is bound 
> 
> foo = 7 
> truelength("foo")    
'foo' has length 3 and truelength 27999 # bound 
> truelength("bar")    
'bar' has length 3 and truelength 0  # not bound 
> .Internal(inspect("foo")) 
@876eb08 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0) # tl=0 of STRSXP vector 
    @81759e8 09 CHARSXP g0c1 [gp=0x21] "foo"  # tl of CHARSXP not shown by inspect 

を::

証明するために

// test.c 
#include <R.h> 
#include <Rdefines.h> 

SEXP truelength(SEXP v) 
{ 
    SEXP s = STRING_ELT(v,0); 
    Rprintf("'%s' has length %d and truelength %d\n", 
        CHAR(s), LENGTH(s), TRUELENGTH(s)); 
    return(R_NilValue); 
} 
+0

あなたがそれが固定されていることを知ってうれしい! –

1

コメントの流れが問題にかなり近く、これは再現することは困難/不可能だ:

同様に
R> x <- 1L:3L 
R> x 
[1] 1 2 3 
R> get("x") 
[1] 1 2 3 
R> matt <- function() { y <- 7L:9L; get("y") } 
R> matt() 
[1] 7 8 9 
R> 

littler経由:

[email protected]:~$ r -e 'x <- 1L:3L; print(get("x"))' 
[1] 1 2 3 
[email protected]:~$ 

我々は、再現性の例を参照する必要があります。あなたのシステムにのみヒットした場合、特にあなたのdata.tableがロードされた後でなければ、あなたはそこを見なければなりません。どういうわけか、「囲み枠のロジックのルックアップシンボル」が頭に浮かんでいるようです。

+0

はい、開発中のdata.tableと関係している可能性があります。私はそれを見てきました;)しかし、それは時にはCレベルでどのようになっているかを知っています。見た目や場所を見つけるのは必ずしも容易ではありません。 Rのコミットログを見ると、 '.GlobalEnv'が(2011年5月現在)変更されたRのバージョンがわからないようになりました。その後のR_UnboundValueとのコミットがありました。ハッシュ値はそこにあるかもしれませんが、何とかバインドされず、 'x'と' get( "x") 'の違いは何ですか?オブジェクトに何が間違っているかを確認できれば、その原因を突き止めることができます。 –

+0

setActiveBindingsで作成されたxはどうですか? – hadley

+0

@hadleyあなたのコメントを見ました。ありがとう、多分。私はまだsetActiveBindingsで遊んでいません。 –

関連する問題