Почему такое поведение при принуждении списка к символу через as.характер ()?

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

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 ответов


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

  1. только если вектор целочисленный и 1,2,3,...п - потом он deparses как 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)

файл справки говорит

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

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

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

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

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