访问R中Filter(is.atomic,eq)显示的原子矢量

时间:2012-01-06 07:00:47

标签: r functional-programming

Filter(is.atomic, something)

返回原子矢量。

1。天气 - 示例here

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

2。 mosaic-plot-as-tree-plot -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。用你的想象力,这些例子并不是唯一的。我怎样才能访问他们的原子载体?

3 个答案:

答案 0 :(得分: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
}

此函数维护元素的名称。用法,使用Vincent的回答列表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()(这是Vincent基本上手写的内容)。

> 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()不会做你认为它做的事情。从Vincent的答案中获取示例列表x,只访问它的原子部分非常简单。 Filter()仅返回第二个元素。那是唯一的原子元素。 Filter(is.atomic, x) 100%相当于:

ind <- sapply(x, is.atomic)
x[ind]

答案 1 :(得分: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

答案 2 :(得分:1)

Filter将返回一个列表。函数lapplysapply通常用于处理列表对象的各个元素。如果您想要使用“[”或“[[”来编号来访问它们,那么您可以使用length(object)确定可接受数字的范围。因此object[[length(object)]]会为您提供最后一个元素(就像tail(object, 1))。