2

我想计算 a 行中元素之间的平均时间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

4

1 回答 1

4

apply,当在数据框上使用时,具有将其强制转换为矩阵的效果。矩阵的模式是可以存储数据框所有列的模式;在您的情况下,您有 class 列,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))

whereavgtime2avgtime接受多个输入而不是 1 的重写版本。

于 2013-07-03T15:58:20.260 回答