2014-03-27 29 views
1

我一直在尋找Stackoverflow幾個小時希望找到我猜的東西是不言而喻的,但似乎沒有人問過(這可能意味着它確實是不言而喻的)。使用tapply或通過功能的非默認設置

我想使用tapplyby來查找數據幀中第一次發生特定事件(第一個非零值)。我之前這樣做的方式是通過

max.col(df, ties.method = c("first")) 

但是不知何故,當與tapply或by結合使用時,這不起作用。下面是一些實施例一數據

FIRM<-as.vector(sample(c("a","b","c","d"),100,replace=T)) 
MOMENT<-as.vector(sample((1990:1995),100,replace=T)) 
EVENT<-as.vector(sample(c("x12","x43","x35","y71","y81","xy1","xy67","yy123","xx901"),100,replace=T)) 
OCCURENCE<-as.vector(sample(c(0,1),100,replace=T)) 
m<-as.data.frame(cbind(FIRM,MOMENT,EVENT,OCCURENCE)) 

因此,這裏是我的嘗試,並沒有工作

  1. tapply(m[,4],m[,3],max.col)#這給剛剛1S爲用得到的載體等於中提到的事件數的長度每一個事件數據集
  2. tapply(m[,4],m[,3],max.col(m, ties.method=c("first")))#match.fun(FUN)中的錯誤: 'max.col(m,ties.method = c(「first」))'不是函數,字符或符號 另外:警告消息:在max.col(m,ties.method = c(「first」))中:引入了NAs d通過強制

2號的確是問題的關鍵。由於我不清楚的原因,一旦將默認的打破平局方法(即「隨機」)更改爲我需要的方式(即「第一個」),max.col就不會被識別爲函數。

此外,我希望能夠找到非零發生的年份。 我認爲一個明智的選擇是將MOMENT列與OCCURENCE列相乘(調用該ID)並查找ID中的第一個非零值(對於每個因子EVENT),保留該ID值並將其他值設爲零

m$MOMENT<-as.numeric(as.character(m$MOMENT)) 
m$OCCURENCE<-as.numeric(as.character(m$OCCURENCE))  
m[,"ID"]<-m$MOMENT * m$OCCURENCE 

我試圖用含有whenif語句和使用break函數的代碼這一點,但它不工作

tapply(m$ID,m$EVENT, function(x) m$ID[i]<- while (m$ID[i] == 0) {m$ID[i] 
        if (m$ID[i]>0) {m$YEAR[i] && break }}) 

這裏的想法是在事件迭代功能,而M $ ID == 0,然後更改值並中斷一旦m $ ID> 0.沒有工作...

任何想法如何解決這個(或更簡單的解決方案)?

回答

2

tapplyFUN參數必須是一個函數,但問題中的代碼提供表達式而不是函數。嘗試:

tapply(m[,4], m[,3], max.col, ties.method = "first") 

這將給在其中在的發生列和第二行具有1中的每個事件的第一行的一個邏輯指示器將選擇這些行:

o <- order(m$EVENT, m$MOMENT) # omit this and next line if already ordered 
m <- m[o,] 

is.first <- ave(m$OCCURENCE == 1, m$EVENT, FUN = function(x) x & !duplicated(x)) 
m[is.first, ] 

REVISED

  • 按事件和年份排序。

  • 請注意,如果可能有隻有零的事件,那麼這些事件將從m[is.first, ]完全省略。

+0

謝謝G.G這工作像一個魅力,一旦我根據年份訂購變量。不確定ave功能是如何工作的,但它確實有效:)!乾杯 – SJDS

1

我不太清楚你想達到什麼,所以這裏只是一些編碼建議。

首先,你需要閱讀help("tapply")李爾如何傳遞參數傳遞給tapply功能:

tapply(m[,4],m[,3],max.col, ties.method="first") 

然而,我懷疑這樣做你所需要的。也許像這樣的東西將是有用的:

m<-data.frame(FIRM,MOMENT,EVENT,OCCURENCE) 
#note how I create the data.frame in a different way 
#in order to avoid coercing all columns to factors 


tapply(m[,4],m[,3],which.max) 
# x12 x35 x43 xx901 xy1 xy67 y71 y81 yy123 
# 2  1  2  3  1  1  3  1  1 

tapply(m[,4],m[,3],function(x) m[which.max(x), "MOMENT"]) 
# x12 x35 x43 xx901 xy1 xy67 y71 y81 yy123 
# 1995 1995 1995 1991 1995 1995 1991 1995 1995 
+0

感謝@Roland,我沒有想到之前的which.max功能。我認爲它給出了最大數量,而不是第一個最大值,所以這個效果也非常出色。 – SJDS

+0

嘿@Roland,我一直在努力讓你的解決方案有效,但它似乎會犯錯誤。結果根據數據的順序而不同(當然可以固定),並且在你的例子中,它給出了xx901,例如錯誤的是1991,應該是1992,x43是給出1995,但應該是1990。 ..這可能涉及which.max如何查找第一個最大值,即由子因素m [,3] ...不確定的子組內的起始位置。無論如何,你的同事通過ave函數的建議完美工作。謝謝你的幫助! – SJDS

+0

當然這取決於訂單。我瞭解到你在數據框架中的第一個位置,而不是在第一年。如果你想要第一年,你需要訂購data.frame或使用不同的方法。 – Roland