2012-05-21 92 views
1

我有一個數據框,其中每列是一個時間系列的數字(從0到8)表示動物求偶過程中的不同行爲。我想檢查是否有一種模式,比如一個給定的行爲更多地被另一個跟隨。我寫了一個函數,讓我做計算遵循一個給定的行爲,在特定的時間間隔後行爲的頻率:R嵌套for循環合併數據幀

> data[,3] 
    [1] 1 1 1 1 7 7 3 3 7 3 1 1 8 1 3 3 3 5 1 1 4 ... 

neighbor <- function(DATA, BEHAVIOR, INTERVAL) 
{ 
total=c(0) 
tmp = data.frame(total=c(0:8),Freq=rep(0,9)) 
number_of_x = which(DATA == BEHAVIOR) 

for(i in number_of_x){ 
       total = append(total,DATA[i+INTERVAL,]) 
} 
tmp = merge(tmp,table(total), by=c("total"), all=T) 
tmp[is.na(tmp)] <- 0 
subset(tmp, select = ncol(tmp)) 
} 

於是我運行函數說,第三列,行爲3,和接下來的行爲在時間(1),我得到我想要的:

> neighbor(as.data.frame(data[,3], 3, 1] 
Freq.y 
0 0.01 
1 0.71 
2 0.01 
3 0.21 
4 0.01 
5 0.04 
6 0.01 
7 0.02 
8 0.00 

現在我想用一個類似的函數來獲得九個行爲的頻率。喜歡的東西:

neighborAll <- function(DATA, INTERVAL) 
{ 
total=c(0) 
tmp = data.frame(total=c(0:8),Freq=rep(0,9)) 
for(a in c(0:8)){ 
number_of_x = which(DATA == a) 
for(i in number_of_x){ 
     total = c(total,DATA[i+INTERVAL,]) 
} 
tmp=merge(tmp, table(total), by = c("total"), all=T) 
tmp[is.na(tmp)] <- 0 
} 
tmp[,3:9] 
} 

> neighborAll(as.data.frame(data[,3], 1) 

我得到:

Error in merge.data.frame(tmp, table(total), by = c("total"), all = T) : 
    there is already a column named ‘Freq.x’ 

任何想法將受到歡迎。由於提前,何塞

+0

一個可重複的例子將會走很長的路我應該算。 –

+0

@lince,如果你想得到答案,你應該提供一個可複製的例子,可以複製並粘貼到R會話中(即使它失敗了)。這可能意味着用虛擬數據創建一個更簡單的代碼片段,這看起來像很多工作。然而,我發現爲stackoverflow準備一個問題是一個有用的學科,我已經多次找到答案,而無需將問題發佈到SO上。代碼應該簡潔;擺脫不需要了解的問題。我最近的問題因爲沒有足夠簡單的例子而受到公正的批評! – SlowLearner

+0

重寫是最好的;如下面的答案所示。但是,上面的問題可以通過在合併之前重命名新列來解決,因爲錯誤消息告訴您有多個同名的列,或者我注意到在All版本中沒有列的子集;它可能是你每次都攜帶比你想要的更多的列,並且它們具有相同的名稱。 – Aaron

回答

0

如果不是爲了得到正確的名稱,每個這些可能是一個班輪。

neighbor <- function(DATA, BEHAVIOR, INTERVAL) { 
    nbins <- 1+max(0, DATA, na.rm = TRUE) 
    out <- tabulate(1+DATA[which(DATA==BEHAVIOR)+INTERVAL], nbins=nbins) 
    names(out) <- 1:nbins - 1 
    out 
} 

neighborAll <- function(DATA, INTERVAL) { 
    out <- sapply(0:max(DATA, na.rm=TRUE), 
     function(BEHAVIOR) neighbor(DATA, BEHAVIOR, INTERVAL)) 
    colnames(out) <- 0:max(DATA, na.rm=TRUE) 
    out 
} 

> x <- c(1, 1, 1, 1, 7, 7, 3, 3, 7, 3, 1, 1 ,8, 1, 3, 3, 3, 5, 1, 1, 4) 

> neighbor(x,3,1) 
0 1 2 3 4 5 6 7 8 
0 1 0 3 0 1 0 1 0 

> neighborAll(x,1) 
    0 1 2 3 4 5 6 7 8 
0 0 0 0 0 0 0 0 0 0 
1 0 5 0 1 0 1 0 0 1 
2 0 0 0 0 0 0 0 0 0 
3 0 1 0 3 0 0 0 2 0 
4 0 1 0 0 0 0 0 0 0 
5 0 0 0 1 0 0 0 0 0 
6 0 0 0 0 0 0 0 0 0 
7 0 1 0 1 0 0 0 1 0 
8 0 1 0 0 0 0 0 0 0 
+0

謝謝Aaron,您的解決方案清晰,簡單,非常優雅。我只在第二個函數的max(DATA)中添加了na.rm = TRUE。這個論壇非常有用,我從你們所有人那裏學到了很多東西。 – lince

+0

好的補充,謝謝。 – Aaron

1

基本上你想要這個:

neighborAll <- function(DATA, INTERVAL, TABLE) 
{ 
    for(i in 1:(nrow(TABLE) - 1)) 
    { 
     neighbors <- DATA[which(DATA == i) + INTERVAL] 
     tab <- table(neighbors) 
     TABLE[TABLE$behavior %in% names(tab), i + 2] <- tab 
    } 
    return(TABLE) 
} 

x<-c(1, 1, 1, 1, 7, 7, 3, 3, 7, 3, 1, 1 ,8, 1, 3, 3, 3, 5, 1, 1, 4) 

behavior <- 0:8 
n <- length(behavior) 
tmp <- matrix(nrow=n, ncol=n) 
colnames(tmp) <- paste("freq", behavior, sep="") 
freqtab <- data.frame(behavior, tmp) 

neighborAll(x, 1, freqtab)