R将带矢量名称的函数应用于每一行

时间:2013-07-03 15:47:06

标签: r apply

我想计算data.frame行中元素之间的平均时间。

> x <- structure(list(`as.Date("2010-12-31")` = structure(c(14974, 14974, 
14974, 14974, 14974), class = "Date"), Date1_P2 = structure(c(14061, 
11566, 11747, 13848, 12965), class = "Date"), Date2_P2 = structure(c(NA, 
10408, 11627, 10074, 6329), class = "Date"), Date3_P2 = structure(c(NA, 
8370, 11566, NA, NA), class = "Date")), .Names = c("as.Date(\"2010-12-31\")", 
"Date1_P2", "Date2_P2", "Date3_P2"), row.names = c("0000001.1", 
"0000004.2", "0000005.2", "0000009.3", "0000010.1"), class = "data.frame")
> x
          as.Date("2010-12-31")   Date1_P2   Date2_P2   Date3_P2
0000001.1            2010-12-31 2008-07-01       <NA>       <NA>
0000004.2            2010-12-31 2001-09-01 1998-07-01 1992-12-01
0000005.2            2010-12-31 2002-03-01 2001-11-01 2001-09-01
0000009.3            2010-12-31 2007-12-01 1997-08-01       <NA>
0000010.1            2010-12-31 2005-07-01 1987-05-01       <NA>

我编写了一个函数来计算每一行。

> avgtime <- function(history){
  difftime <- vector("numeric", length=9)
  i <- 2
  while(!is.na(history[i]) & i < 4){
    difftime[i-1] <- history[i-1] - history[i]
    i <- i + 1
  }
  return(mean((unlist(difftime[which(difftime!=0)]))))
}
> for(i in 1:nrow(x)){print(avgtime(x[i,]))}
[1] 913
[1] 2283
[1] 1673.5
[1] 2450
[1] 4322.5

但是当我尝试将apply发送到我的data.frame时,我遇到了问题。

> apply(x, 1, avgtime)
Error in history[i - 1] - history[i] : 
  non-numeric argument to binary operator

什么是更恰当的apply电话?

1 个答案:

答案 0 :(得分:4)

apply,当在数据框上使用时,具有将其强制转换为矩阵的效果。矩阵的模式是可以存储数据帧的所有列的模式;在您的情况下,您有类Date的列,这意味着矩阵将是character。这就是您的apply来电失败的原因。

在使用x之前,您可以做的是将apply的所有(必填)列转换为数字。您没有使用任何特定于日期的数据功能,因此您不应该丢失任何内容。

x[] <- lapply(x, unclass)
apply(x, 1, avgtime)

更复杂但更可能更优雅的方法(因为它不涉及强制或矩阵/数组操作)将使用mapply

mapply(x[,1], x[,2], x[,3], x[,4], avgtime2)
#or
do.call(mapply, c(list(avgtime2), x))

其中avgtime2avgtime的重写版本,可接受多个输入而不是1。