1

我一直在搜索 Stackoverflow 几个小时,希望能找到一些我猜想是不言而喻的东西,但似乎没有人问过(这可能意味着它确实是不言而喻的)。

我想使用tapplyorby来查找特定事件第一次出现在数据框中(第一个非零值)。我以前这样做的方式是通过

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)# 这为每个 EVENT 提供 1,结果向量的长度等于数据集中提到的 EVENT 的数量
  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")) :强制引入的 NA

2号确实是问题的症结所在。由于我不清楚的原因,一旦您将默认的平局打破方法(即“随机”)更改为我需要的方法(即“第一”),max.col 就不会被识别为函数。

此外,我希望能够找到发生非零的年份。我认为一个明智的选择是将 MOMENT 列与 OCCURENCE 列相乘(称为该 ID)并在 ID 中查找第一个非零值(对于每个因子事件)保持该 ID 值并将其他值变为零

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

我尝试使用包含whenandif语句和 using的函数对此进行编码,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 时在 EVENT 上迭代函数,然后更改值并在 m$ID > 0 时中断。没用...

关于如何解决这个问题(或更简单的解决方案)的任何想法?

4

2 回答 2

2

FUN参数tapply必须是一个函数,但问题中的代码提供了一个表达式,而不是一个函数。尝试这个:

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

这将给出每个事件中第一行的逻辑指示符,在 OCCURENCE 列中有 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, ]

修改

  • 按事件和年份排序。

  • 请注意,如果可能存在只有零的事件,则此类事件将完全从m[is.first, ].

于 2014-03-27T12:09:39.230 回答
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 
于 2014-03-27T12:16:39.170 回答