Почему такое поведение при приведении списка к символу с помощью as.character ()? - PullRequest
9 голосов
/ 29 сентября 2011

В процессе (в основном) ответа на этот вопрос я наткнулся на то, что, как мне кажется, я действительно уже видел раньше. Допустим, у вас есть список:

l <- list(a = 1:3, b = letters[1:3], c = runif(3))

Попытка принудить l к различным типам возвращает ошибку:

> as.numeric(l)
Error: (list) object cannot be coerced to type 'double'
> as.logical(l)
Error: (list) object cannot be coerced to type 'logical'

Однако мне, видимо, разрешено приводить список к персонажу, я просто не ожидал такого результата:

> as.character(l)
[1] "1:3"                                                        
[2] "c(\"a\", \"b\", \"c\")"                                     
[3] "c(0.874045701464638, 0.0843329173512757, 0.809434881201014)"

Скорее, если бы мне было разрешено приводить списки к персонажу, я бы подумал, что увижу поведение, похожее на это:

> as.character(unlist(l))
[1] "1"                  "2"                  "3"                  "a"                  "b"                 
[6] "c"                  "0.874045701464638"  "0.0843329173512757" "0.809434881201014"

Обратите внимание, что способ первоначального указания элементов списка влияет на вывод as.character:

l <- list(a = c(1,2,3), b = letters[1:3], c = runif(3))
> as.character(l)
[1] "c(1, 2, 3)"                                                 
[2] "c(\"a\", \"b\", \"c\")"                                     
[3] "c(0.344991483259946, 0.0492411875165999, 0.625746068544686)"

У меня два вопроса:

  1. Как as.character извлекает информацию из моего первоначального создания списка l, чтобы выплюнуть 1:3 против c(1,2,3).
  2. При каких обстоятельствах я бы хотел это сделать? Когда я захочу позвонить as.character() в списке и получить выходные данные этой формы?

Ответы [ 2 ]

7 голосов
/ 29 сентября 2011

Для нетривиальных списков as.character использует deparse для генерации строк.

  1. Только если вектор является целым числом и 1,2,3, ...,n - затем он отклоняется как 1:n.

    c(1,2,3), удваивается, тогда как 1:3 является целым числом ...

  2. Не знаю: -)

... но посмотрите на deparse, если вы хотите понять as.character здесь:

deparse(c(1L, 2L, 3L)) # 1:3
deparse(c(3L, 2L, 1L)) # c(3L, 2L, 1L)
deparse(c(1, 2, 3))    # c(1, 2, 3)
6 голосов
/ 29 сентября 2011

В справочном файле написано:

Для списков он удаляет элементы по отдельности, за исключением того, что он извлекает первый элемент векторов длины одна единица.

I 'Я видел это раньше, пытаясь ответить на вопрос [не в сети] о grep.Рассмотрим:

> x <- list(letters[1:10],letters[10:19])
> grep("c",x)
[1] 1 2

grep использует as.character для x, в результате чего оба имеют c(, оба компонента совпадают.Потребовалось некоторое время, чтобы выяснить.

На " Почему он это делает? ", я бы предположил, что один из членов ядра R хотел, чтобы он это сделал.

...