2012-01-30 26 views
2

lapply函数的工作原理存在根本性问题。我想分类列表中每个向量的每个成员。更改列表中的每个向量

我的列表:

s <- list(
    a = c(1, 20, 300), 
    b = c(1.1, 20.1, 300.1), 
    c = c(1.2, 20.2, 300.3) 
) 

我的分类功能:

classify <- function(n, peaks){ 
    which(abs(peaks-n)==min(abs(peaks-n))) 
} 

我峰:

peaks <- c(1.27350, 20.32662, 300.02650) 

如果本身我classify US $ C,我得到的结果,我期望:

> sapply(s$c,classify,peaks) 
[1] 1 2 3 

但是当我尝试所有的向量一次分类,我得到这个:

> lapply(s,classify,peaks) 
$a 
[1] 3 //should be 1,2,3 

$b 
[1] 3 //should be 1,2,3 

$c 
[1] 1 //should be 1,2,3 

为什么我收到,我这样做的结果?我如何得到我想要的结果?

+0

里奇有一些很好的评论。我仍然在努力理解为什么'1,2,3'是你期望的结果。 'classify'旨在接受'n'和'peaks'的矢量吗? – joran 2012-01-30 16:24:06

+0

'n'应该只是一个数字。我原以为'lapply(S,分类,峰值)'会为我想,因为单曲<-lapply(s_as_text,as.integer)' “numericized” s_as_text来的工作。 – dnagirl 2012-01-30 17:05:20

回答

2

首先,样式点:使用which.min找到最小的位置。

classify <- function(n, peaks){ 
    which.min(abs(peaks-n)) 
} 

第二,把你的代码打破了一下,看看发生了什么。

abs(peaks - s$a) #3rd value is smallest 
abs(peaks - s$b) #3rd value is smallest 
abs(peaks - s$c) #1st value is smallest 

这些指数是什么被从调用返回到lapply


基于您的评论,我想你的问题是,lapply行为的载体,当你真的想调用只是一切都调用一次,因为classify中的每个元素已经被矢量化。试试这个:

if(is.list(s)) lapply(s, classify, peaks = peaks) else classify(s, peaks) 
+0

感谢风格点。所以,对于第二点,问题是我的功能需要以不同的方式处理矢量。因此,在编写处理列表的函数时,通常会对输入进行什么样的理智检查? – dnagirl 2012-01-30 17:43:29

+0

@dnagirl:我认为你想要的完整性检查只是'is.list(s)'。看到我更新的答案。 – 2012-01-31 09:54:02

4

如何回合

> lapply(s,sapply,classify,peaks) 
$a 
[1] 1 2 3 

$b 
[1] 1 2 3 

$c 
[1] 1 2 3 
1

lapply(s, function(x) classify(x, peaks))将列表s的每个元素传递为n在功能分类。 lapply(s, classify, peaks)通过峰值n进行分类。