2012-01-06 1 views
-2
Filter(is.atomic, something) 

возвращает атомные векторы.Доступ к атомным векторам, показанным фильтром (is.atomic, eq) в R

1. Погода -example here

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

2. мозаичные сюжетно-в-дерево-участок -example here

> 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. Используйте свое воображение, примеры не являются исключительными. Как я могу получить доступ к своим атомным векторам?

+8

Это не то, что задвижки для (ответные атаки). Я не спускал вниз, но я могу понять, почему кто-то может - ваш вопрос не очень ясен Вы просто хотите получить доступ к векторам в объектах, на которые вы ссылаетесь? Вы хотите пересечь произвольный список и вернуть атомные векторы? Как насчет того, что вы даете явный пример ** с ** ожидаемым выходом, поэтому очень ясно, что вы хочу ответить –

+2

+1 для ответа Гэвина, но я думаю, что разумно спросить «почему нисходящий?» более нейтральным тоном - для целей образования ... –

ответ

3

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

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 <- 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() (что Винсент handcoded в основном).

> 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] 
+0

... есть какая-то функция, которая возвращает себя «Я : = (lambda x. x) '? Я имею в виду' rapply (x, returnTheAtomicVectorsAsTheyAre) '?' dput (rapply (x, unlist)) 'возвращает' 1: 24', не сохраняя структуру. – hhh

+0

@hh: посмотреть? –

1

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

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

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 
1

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

Смежные вопросы