Доступ к атомным векторам, показанным фильтром (is.atomic, eq) в R - PullRequest
0 голосов
/ 06 января 2012
Filter(is.atomic, something)

возвращает атомные векторы.

1.Погода - пример здесь

> Filter(is.atomic, study)
$region
[1] "Hamburg" "Bremen" 

2.Мозаика-сюжет-как-дерево-сюжет-пример здесь

> Map(function(x) Filter(is.atomic, x), ls())
$g
[1] "g"

$lookup
[1] "lookup"

$req.data
[1] "req.data"

$tmp
[1] "tmp"

$tmp1
[1] "tmp1"

Посмотрите, что их позиции могут быть произвольными, я могу иметь малейшее представление об их структуре данных, поэтому не могу использоватьvar$some$...$vector.Я чувствую потребность в ?Position.Используйте свое воображение, примеры не являются эксклюзивными.Как я могу получить доступ к их атомным векторам?

Ответы [ 3 ]

3 голосов
/ 06 января 2012

Чтобы сгладить список и получить доступ к атомным векторам, вы можете использовать следующую функцию:

flatten.list <- function(x){
  y <- list()
  while(is.list(x)){
    id <- sapply(x,is.atomic)
    y <- c(y,x[id])
    x <- unlist(x[!id],recursive=FALSE)
  }
  y
}

Эта функция поддерживает имена элементов. Использование, используя список x из ответа Винсента:

x <- list(
   list(1:3, 4:6),
   7:8,
   list( list( list(9:11, 12:15), 16:20 ), 21:24 )
)

тогда:

> flatten.list(x)
[[1]]
[1] 7 8

[[2]]
[1] 1 2 3

[[3]]
[1] 4 5 6

[[4]]
[1] 21 22 23 24

...

Чтобы рекурсивно выполнить действие со всеми атомарными элементами в списке, используйте rapply() (это то, что Винсент в основном кодирует вручную).

> rapply(x,sum)
[1]  6 15 15 30 54 90 90

> rapply(x,sum,how='list')
[[1]]
[[1]][[1]]
[1] 6

[[1]][[2]]
[1] 15


[[2]]
[1] 15

...

См. Также ?rapply

PS: Ваш код Map(function(x) Filter(is.atomic, x), ls()) не имеет смысла. ls() возвращает символьный вектор, поэтому каждый элемент этого символьного вектора будет возвращен как часть списка. Это вообще ничего вам не говорит.

Рядом с этим Filter() не делает то, во что вы верите. Если взять список примеров x из ответа Винсента, то получить доступ только к его атомным частям довольно просто. Filter() возвращает только второй элемент. Это единственный атомный элемент. Filter(is.atomic, x) 100% эквивалентно:

ind <- sapply(x, is.atomic)
x[ind]
1 голос
/ 06 января 2012

Filter вернет список.Функции lapply и sapply обычно используются для обработки отдельных элементов объекта списка.Если вместо этого вы хотите получить к ним доступ по номеру, используя «[» или «[[» », то вы можете определить диапазон допустимых номеров с помощью length(object).Так что object[[length(object)]] даст вам последний элемент (как (tail(object, 1)).

1 голос
/ 06 января 2012

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

Поскольку вы предлагаете нам «использовать наше воображение», я предполагаю, что у вас есть иерархическая структура данных, то есть список списков ... списков, глубина которых неизвестна. Например,

x <- list(
  list(1:3, 4:6),
  7:8,
  list( list( list(9:11, 12:15), 16:20 ), 21:24 )
)

Листья - это векторы, и вы хотите что-то сделать с этими векторами.

Например, вы можете объединить их в один вектор: это то, что делает функция unlist.

unlist(x)

Вы также можете захотеть все листья в списке, то есть список векторов. Вы можете легко написать (рекурсивную) функцию, которая исследует структуру данных и постепенно строит этот список следующим образом.

leaves <- function(u) {
  if( is.atomic(u) ) { return( list(u) ) }
  result <- list()
  for(e in u) {
    result <- append( result, leaves(e) )
  }
  return(result)
}
leaves(x)

Вы также можете захотеть применить функцию ко всем листьям, сохранив при этом структуру данных.

happly <- function(u, f, ...) {
  if(is.atomic(u)) { return(f(u,...)) }
  result <- lapply(u, function(v) NULL) # List of NULLs, with the same names
  for(i in seq_along(u)) {
    result[[i]] <- happly( u[[i]], f, ... )
  }
  return( result )
}
happly(x, range) # Apply the "range" function to all the leaves
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...