#r
#r
Вопрос:
Каким-то образом, иногда, я оказываюсь в таком состоянии, как это :
> x
[1] 1 2 3
> get("x")
Error in get("x") : object 'x' not found
> x
[1] 1 2 3
Я не могу воспроизвести это надежно. Какие вещи я мог сделать неправильно в своем C-коде? Почему при вводе x
в командной строке это будет найдено, а get("x")
нет? В чем внутренняя разница между x
и get("x")
?
Любые подсказки очень ценятся. Я начал видеть это с версии 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 %dn",
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 %dn", 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 %dn", length(levels), TYPEOF(s),
CHAR(s), s, LENGTH(s), TRUELENGTH(s));
}
return(R_NilValue);
}
и для его запуска :
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 должен запускаться каждый раз заново.
Комментарии:
1. Не могли бы вы уточнить
my C code has also been changing too
. Я не знаком с C, но вам определенно следует опубликовать код на C и подождать, пока @Dirk Eddelbuettel придет в себя. Кстати, я не могу воспроизвести это поведение.2. но гораздо важнее раскрыть свой код. =)
3. @aL3xa Не в этом случае. Я являюсь соавтором
data.table
пакета — мне нужно было бы показать вам, как загрузить его и запустить в режиме разработки (версии для разработки), затем запустить вещи определенным образом, и даже тогда это не воспроизводимо для меня. Я уже говорил, что не могу воспроизвести в вопросе. Это общий вопрос о разнице между вводомx
в командной строке и использованиемget
. Хорошо?4. Может быть, проблема со средой? Что это
find("x")
дает?5. @James. Hi.
find()
находит это иobjects()
перечисляет, поэтому кажется, что это есть в.GlobalEnv
, ноget()
так не думает.
Ответ №1:
Это действительно оказался мой C-код. Я знал, что R иногда использует TRUELENGTH, но я не думал о CHARSXP. Когда имя переменной совпадает с некоторым символьным значением, ИСТИННАЯ длина CHARSXP используется R для хранения внутреннего значения хэша, см. main/ envir.c . Мой SET_TRUELENGTH в CHARSXP искажал хэш. Спасибо Саймону Урбанеку за объяснение этого, и спасибо за все советы и идеи в комментариях.
Чтобы продемонстрировать :
$ 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
где находится код C, позволяющий увидеть ИСТИННУЮ длину CHARSXP :
// 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 %dn",
CHAR(s), LENGTH(s), TRUELENGTH(s));
return(R_NilValue);
}
Комментарии:
1. Рад знать, что вы это зафиксировали!
Ответ №2:
Поток комментариев довольно близок к проблеме, и это кажется трудным / невозможным воспроизвести:
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:
edd@max:~$ r -e 'x <- 1L:3L; print(get("x"))'
[1] 1 2 3
edd@max:~$
Нам нужно было бы увидеть воспроизводимый пример. Если это происходит только в вашей системе, и особенно только после того, как, скажем, была загружена ваша data.table, тогда вам нужно посмотреть там. Каким-то образом логика «символа поиска во вложенных фреймах», похоже, была сбита с толку.
Комментарии:
1. Да, это, вероятно, как-то связано с data.table, находящимся в разработке. Я смотрел на это 😉 но вы знаете, как это иногда бывает на уровне C. Не всегда легко найти или знать, где искать. Просматривая журнал фиксации R, я увидел, что
.GlobalEnv
теперь он хэширован (по состоянию на май 2011), не уверен, в какую версию R это изменение попало. Последующие коммиты были связаны с R_UnboundValue . Так может ли быть хэшированное значение, но оно каким-то образом не привязано, и в этом разница междуx
иget("x")
? Если я смогу установить, что не так с объектом, я, возможно, смогу выяснить, что вызвало это.2. Как насчет x, созданного с помощью setActiveBindings?
3. @hadley только что увидел ваш комментарий. Спасибо, может быть. Я еще не играл с setActiveBindings.
4. @Dirk теперь добавили пример воспроизведения. Возможно, слишком локализовано, лучше использовать r-devel?
5. Я видел ваше обновление, но у меня не было времени поиграть. И да, r-devel кажется лучшей идеей.