5

例如,我有一个矩阵k

> k
  d e
a 1 3
b 2 4

我想在 k 上应用一个函数

> apply(k,MARGIN=1,function(p) {p+1})
a b
d 2 3
e 4 5

但是,我还想打印该rowname行的 ,apply以便我可以知道该函数当时应用于哪一行。

它可能看起来像这样:

apply(k,MARGIN=1,function(p) {print(rowname(p)); p+1})

但我真的不知道如何在 R 中做到这一点。有人知道吗?

4

4 回答 4

12

这是我认为您要问的一个巧妙的解决方案。(为了清楚起见,我将输入矩阵称为输入矩阵- 在此示例中,有 2 列和 10 行,并且行被命名为 abc1 到 abc10。matkmat

在下面的代码中,结果out1是您想要计算的东西(apply 命令的结果)。结果与它out2相同,out1只是它打印出它正在处理的行名(我每行设置了 0.3 秒的延迟,所以你可以看到它确实这样做了 - 当你希望代码运行完整时将其删除速度明显!)

我想出的技巧是将行号(1 到 n)cbind 到mat(以创建一个带有一个附加列的矩阵)的左侧,然后使用它来引用mat. 注意x = y[-1]表示函数内的实际计算(这里加 1)忽略行号的第一列的行,这意味着它与为out1. 无论您想对行执行什么类型的计算,都可以通过这种方式完成 - 只需假装y从未存在,然后使用x. 希望这可以帮助。

set.seed(1234)
mat = as.matrix(data.frame(x = rpois(10,4), y = rpois(10,4)))
rownames(mat) = paste("abc", 1:nrow(mat), sep="")
out1 = apply(mat,1,function(x) {x+1})
out2 = apply(cbind(seq_len(nrow(mat)),mat),1,
             function(y) {
                           x = y[-1]
                           cat("Doing row:",rownames(mat)[y[1]],"\n")
                           Sys.sleep(0.3)
                           x+1
                          }
            )

identical(out1,out2)
于 2012-06-09T06:50:45.830 回答
4

您可以在 apply 调用之外使用变量来跟踪行索引并将行名称作为额外参数传递给您的函数:

idx <- 1
apply(k, 1, function(p, rn) {print(rn[idx]); idx <<- idx + 1; p + 1}, rownames(k))
于 2012-06-09T00:15:01.107 回答
0

这应该有效。该cat()函数是您在评估函数期间打印结果时要使用的函数。paste(),相反,只返回一个字符向量,但不将其发送到命令窗口。

下面的解决方案使用一个作为闭包创建的计数器,允许它“记住”该函数之前运行了多少次。注意全局 assign 的使用<<-。如果您真的想了解这里发生了什么,我建议您阅读此 wiki https://github.com/hadley/devtools/wiki/

请注意,可能有更简单的方法可以做到这一点;我的解决方案假定无法使用 apply 函数中的典型方式访问当前行的行号或行名。如前所述,这在循环中是没有问题的。

k <- matrix(c(1,2,3,4),ncol=2)
rownames(k) <- c("a","b")
colnames(k) <- c("d","e")


make.counter <- function(x){
    i <- 0
    function(){
        i <<- i+1
        i   
    }
}

counter1 <- make.counter()

apply(k,MARGIN=1,function(p){
    current.row <- rownames(k)[counter1()]
    cat(current.row,"\n")
    return(p+1)
})
于 2012-06-08T23:02:41.950 回答
-3

据我所知,你不能用 来做到这一点apply,但你可以遍历rownames你的数据框。蹩脚的例子:

lapply(rownames(mtcars), function(x) sprintf('The mpg of %s is %s.', x, mtcars[x, 1]))
于 2012-06-08T22:55:59.287 回答