【问题标题】:Looping through an id using lapply() in R在 R 中使用 lapply() 遍历一个 id
【发布时间】:2014-10-24 12:56:38
【问题描述】:

我写了一个这样的函数:

myfunc <- function(data, c1, c2, c3) {
          res <- data*c1*c2*c3
          return(res)
          }   

myfunc 应用于向量data 我可以使用

lapply(data, myfunc, c1=2, c2=3, c3=4)

但我必须循环遍历一个 id 以及向量 data,以便结果向量(或矩阵)的每一行都包含一个 id 和相应的结果。

所以对于简单的情况,这将是:

myfunc <- function(id, data, c1, c2, c3) {
          res <- data*c1*c2*c3
          return(c(id, res))
          }   

但我不能在上面使用lapply。 我已经尝试将所有输入(id, data, c1, c2, c3)放入矩阵中以使用apply

apply(matrix, 1, myfunc)

但它不起作用。

那么实现这一目标的最佳方法是什么?

提前致谢!

编辑:

这可能是数据矩阵:

      id data c1  c2  c3
 [1,] 32 1.12  2 2.5 2.8
 [2,] 33 1.14  2 2.5 2.8
 [3,] 34 1.21  2 2.5 2.8
 [4,] 35 1.22  2 2.5 2.8
 [5,] 36 1.27  2 2.5 2.8
 [6,] 37 1.30  2 2.5 2.8
 [7,] 38 1.32  2 2.5 2.8
 [8,] 39 1.36  2 2.5 2.8
 [9,] 40 1.44  2 2.5 2.8
[10,] 41 1.45  2 2.5 2.8

列 id 应循环通过,myfunc 应应用于其他列。 我期望(或要求)这样的结果:

      id   res
 [1,] 32 15.68
 [2,] 33 15.96
 [3,] 34 16.94
 [4,] 35 17.08
 [5,] 36 17.78
 [6,] 37 18.20
 [7,] 38 18.48
 [8,] 39 19.04
 [9,] 40 20.16
[10,] 41 20.30

【问题讨论】:

  • 我们可以提供一个可重现的示例(具有预期结果)吗?

标签: r apply lapply


【解决方案1】:

我个人更愿意使用apply

x <- data.frame(id = 32:41, 
                data = c(1.12, 1.14, 1.21, 1.22, 1.27, 1.3, 1.32, 1.36, 1.44, 1.45), 
                c1 = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), 
                c2 = c(2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5), 
                c3 = c(2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8, 2.8))
x$res <- apply(x[,-1],1,prod)
x[, c("id", "res")]

【讨论】:

  • 我就是这样做的
【解决方案2】:

无需使用函数,使用data.table 这是您数据的原子示例:

library(data.table)

lst = list(id=c(32,33,34), data=c(1.12,1.14,1.21), c1=rep(2,3),c2=rep(2.5,3),c3=rep(2.8,3))
M = do.call(cbind, lst)

 #     id data c1  c2  c3
#[1,] 32 1.12  2 2.5 2.8
#[2,] 33 1.14  2 2.5 2.8
#[3,] 34 1.21  2 2.5 2.8

dt = as.data.table(M)

我们可以继续:

dt[,res:=data*c1*c2*c3]
as.matrix(dt[,list(id,res)])
#     id   res
#[1,] 32 15.68
#[2,] 33 15.96
#[3,] 34 16.94

【讨论】:

  • 嗯,实际上这个函数要复杂得多。我只是想指出有常数和一个向量。
  • 我看不出问题出在哪里,如果 f 是你的函数:dt[,res:=f(data,c1,c2,c3)]
  • 好的,我明白了。对不起,我只是没有得到它......似乎是一种可行的方式
  • 尤其是我有大量数据!
【解决方案3】:

为什么在数据框中没有数据,然后:

> ddf$res = with(ddf, data*c1*c2*c3)
> ddf
      id data c1  c2  c3   res
[1,]  32 1.12  2 2.5 2.8 15.68
[2,]  33 1.14  2 2.5 2.8 15.96
[3,]  34 1.21  2 2.5 2.8 16.94
[4,]  35 1.22  2 2.5 2.8 17.08
[5,]  36 1.27  2 2.5 2.8 17.78
[6,]  37 1.30  2 2.5 2.8 18.20
[7,]  38 1.32  2 2.5 2.8 18.48
[8,]  39 1.36  2 2.5 2.8 19.04
[9,]  40 1.44  2 2.5 2.8 20.16
[10,] 41 1.45  2 2.5 2.8 20.30

【讨论】:

  • 我喜欢那个,不需要额外的包。
  • 不要失去耐心 ;) 只是必须尝试一下。
【解决方案4】:

除非我很笨,否则这可能很简单。

那么,你明白如何使用 lapply 创建向量 res 了吧?只需将其与您的 id 列一起加入即可。它们的顺序相同,因此 ID 将匹配。

cbind(data$id, res)

【讨论】:

  • 我已经考虑过了,但我正在寻找一种更优雅的方式
猜你喜欢
  • 2020-10-16
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-10-16
  • 2020-06-08
  • 2016-12-01
  • 1970-01-01
相关资源
最近更新 更多