2013-03-05 110 views
3

我想用apply来遍历矩阵的行,我想在我的函数中使用当前行的rowname。看来你不能直接在函数中使用rownamescolnames,dimnamesnames。我知道我可以根据this question中的信息创建一个解决方法。R:rownames,colnames,dimnames和name

但我的问题是,apply如何在它的第一个参数中处理数组的行名和列名,以及如何将名称赋值给由apply调用的函数内部创建的对象?这似乎有点不一致,我希望通过下面的例子来展示。是否有这样设计的原因?

# Toy data 
m <- matrix(runif(9) , nrow = 3) 
rownames(m) <- LETTERS[1:3] 
colnames(m) <- letters[1:3] 
m 
      a   b   c 
A 0.5092062 0.3786139 0.120436569 
B 0.7563015 0.7127949 0.003358308 
C 0.8794197 0.3059068 0.985197273 

# These return NULL 
apply(m , 1 , FUN = function(x){ rownames(x) }) 
NULL 
apply(m , 1 , FUN = function(x){ colnames(x) }) 
NULL 
apply(m , 1 , FUN = function(x){ dimnames(x) }) 
NULL 

# But... 
apply(m , 1 , FUN = function(x){ names(x) }) 
    A B C 
[1,] "a" "a" "a" 
[2,] "b" "b" "b" 
[3,] "c" "c" "c" 
# This looks like a column-wise matrix of colnames, with the rownames of m as the column names to me 

# And further you can get... 
n <- apply(m , 1 , FUN = function(x){ names(x) }) 
dimnames(n) 
[[1]] 
NULL 

[[2]] 
[1] "A" "B" "C" 

# But you can't do... 
apply(m , 1 , FUN = function(x){ n <- names(x); dimnames(n) }) 
NULL 

我只是想了解在内部应用会发生什么?非常感谢。

回答

7

我觉得你的困惑源于这样一个事实,即apply没有将一个数组(或矩阵)传递给FUN中指定的函数。

它依次通过矩阵的每一行。每行本身是“唯一”的一个(命名)向量:

> m[1,] 
     a   b   c 
0.48768161 0.61447934 0.08718875 

所以你的函数只有这个命名向量来处理。

对于你的中间例如,如记载于apply

如果每次调用FUN返回长度为n的矢量,然后应用返回 尺寸c(N,暗淡(X)[MARGIN的阵列]),如果n> 1。如果n等于1,则 apply将返回一个向量,如果MARGIN长度为1并且数组为 dimension dim(X)[MARGIN]否则返回。

所以function(x) names(x)为每一行返回一个长度为3的向量,所以最终的结果就是你看到的矩阵。但是该矩阵在apply函数的结尾处构造,其中FUN的结果单独应用于每行。