2013-07-03 3 views
2

Я хочу рассчитать среднее время между элементами в строке data.frame.R применить функцию с именами векторов к каждой строке

> 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

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)) 

где avgtime2 является переписан версию avgtime принимать несколько входов, а не 1.

+0

Я считал «mapply», но на самом деле у меня есть список около двадцати предметов, и это было утомительно. – gregmacfarlane

Смежные вопросы