0

我对 R 还很陌生,所以把它当作它的价值。

我编写了一个函数,它接受 4 个参数并返回一个数据帧。精简版如下所示。

Advantage <- function(tRos, tTat, cRos, cTat){
  #case 1.1 tRos is lower
  if((tRos > 0 | cRos > 0) & cRos > tRos & cTat < tTat){
    tRosAd <- (cRos - tRos) * cTat * -1
    tTatAd <- (tTat - cTat) * tRos
    r <- c(tRosAd, tTatAd, 1.1)
  }
  else if((tRos > 0 | cRos > 0) & cRos < tRos & cTat > tTat){
    #case 1.2 tRos is higher
    r <- Advantage(cRos, cTat, tRos, tTat)
    r <- r * -1
    r[3] <- 1.2
  }
  r <- data.frame(rosAd = r[1], tatAd = r[2], cat = r[3])
  return(r)
}

然后我需要做的是按年份和 sic 代码对数据进行子集化,然后针对该数据运行函数。

我所做的非常丑陋,非常缓慢,并且有效,但肯定不是最好的方法,如下所示。

bDf <- data.frame()
for (yr in unique(aDf$year)){
  #Subset years
  tmp <- subset(aDf, year == yr)
  for(sc in unique(tmp$sic2)){
    #subset sics
    tmp2 <- subset(tmp, sic2 == sc)
    medRos <- median(tmp2$ros)
    medTat <- median(tmp2$tat)
    for (gvk in unique(tmp2$gvkey)){
      #subset individual gvkeys in the sics
      tmp3 <- subset(tmp2, gvk == gvkey)
      x <- Advantage(tmp3$ros, tmp3$tat, medRos, medTat)
      x <- cbind(tmp3, x)
      bDf <- rbind(bDf, x)
    }
  }
}

我最初让函数返回一个列表,然后尝试将该函数应用于数据框并返回列表,但它一直在切断最后一列。

它看起来像下面这样:

outPut <- Advantage(tmp2$ros, tmp2$tat, median(tmp2$ros), median(tmp2$tat))

任何有关如何纠正我丑陋代码的建议都将不胜感激。我有一种感觉,这可能是 plyr 包中的一行,但我还没有弄清楚。

数据如下所示:

      gvkey year   at   ni sic sales        roa        ros       tat sic2
17857  1266 1966 5.21 0.06 100  1.06 0.01151631 0.05660377 0.2034549   10
17858  1266 1967 5.78 0.31 100  1.28 0.05363322 0.24218750 0.2214533   10
17859  1266 1968 6.54 0.79 100  1.80 0.12079511 0.43888889 0.2752294   10
17860  1266 1969 6.77 0.22 100  1.88 0.03249631 0.11702128 0.2776957   10
17861  1266 1970 8.57 0.15 100  2.42 0.01750292 0.06198347 0.2823804   10
17862  1266 1971 9.02 0.18 100  3.09 0.01995565 0.05825243 0.3425721   10

每个 gvkey 对应一个唯一的公司。我从每个部门 (sic2) 中获取每年的 ros & tat 中位数,并将该部门内的每家公司与该部门在给定年份的中位数进行比较。

4

1 回答 1

0

外部的两个循环可以用一个ddply调用替换,内部的一个循环可以替换为第二个。我保留了tmp2tmp3名称以显示它们在您的原始代码中对应的内容。

library("plyr")
bDf <- ddply(aDf, .(year, sic2), function(tmp2) {
  medRos <- median(tmp2$ros)
  medTat <- median(tmp2$tat)
  ddply(tmp2, .(gvkey), function(tmp3) {
    Advantage(tmp3$ros, tmp3$tat, medRos, medTat)
  })
})

您的函数存在问题Advantage:在 1.2 的情况下,Advantage返回 a data.frame,但该块中的其余代码将其视为返回向量。此外,这两种情况并未涵盖所有可能性(例如,对于您提供的示例数据,两种情况标准都不满足)。如果你让你的Advantage函数工作(并返回一个带有适当列的 data.frame),那么这就提供了循环你想要的子集的方法。

于 2013-07-15T18:19:08.640 回答