使用列表存储R中的双循环(for-loop)的结果

时间:2014-04-03 18:22:10

标签: r for-loop row

我想使用for循环计算各行的元素。 我有两个data.frames

  1. df:包含所有交易日股票的数据
  2. 事件:仅包含股票事件日的数据
  3. 即使对于这个特定的例子可能有一个更容易的方法,我想知道如何在循环中循环(for循环)来完成这样的任务。

    首先,我的data.frames:

    comp1 <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3)
    date1 <- c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5)
    ret <- c(1.2,2.2,-0.5,0.98,0.73,-1.3,-0.02,0.3,1.1,2.0,1.9,-0.98,1.45,1.71,0.03)
    df <- data.frame(comp1,date1,ret)
    comp2 <- c(1,1,2,2,2,3,3)
    date2 <- c(2,4,1,2,5,4,5)
    q <- paste("")
    events <- data.frame(comp2,date2,q)
    
    df
    
    #    comp1 date1   ret
    # 1      1     1  1.20
    # 2      1     2  2.20
    # 3      1     3 -0.50
    # 4      1     4  0.98
    # 5      1     5  0.73
    # 6      2     1 -1.30
    # 7      2     2 -0.02
    # 8      2     3  0.30
    # 9      2     4  1.10
    # 10     2     5  2.00
    # 11     3     1  1.90
    # 12     3     2 -0.98
    # 13     3     3  1.45
    # 14     3     4  1.71
    # 15     3     5  0.03
    
    events
    
    #   comp2 date2 q
    # 1     1     2  
    # 2     1     4  
    # 3     2     1  
    # 4     2     2  
    # 5     2     5  
    # 6     3     4  
    # 7     3     5  
    

    我想计算df $ ret。举个例子,我们只需要2 * df $ ret。每个事件日的结果应存储在mylist中。最终输出应该是data.frame&#34; events&#34;用一列&#34; q&#34;我希望存储计算结果。

    # important objects:
    companies <- as.vector(unique(df$comp1)) # all the companies (here: 1, 2, 3)
    days <- as.vector(unique(df$date1)) # all the trading-days (here: 1, 2, 3, 4, 5)
    mylist <- vector('list', length(companies)) # a list where the results should be stored for each company
    

    我想出了一些不起作用的代码。但我仍然认为它应该是这样的:

    for(i in 1:nrow(events)) {
      events_k <- events[which(comp1==companies[i]),] # data of all event days of company i
      df_k <- df[which(comp2==companies[i]),] # data of all trading days of company i
    
      for(j in 1:nrow(df_k)) {
        events_k[j, "q"] <- df_k[which(days==events_k[j,"date2"]), "ret"] * 2
    
    
      }
      mylist[i] <- events_k   
    }
    

    我不了解如何在另一个循环中设置循环以及如何将结果存储在mylist中。任何帮助表示赞赏!!

    谢谢!

1 个答案:

答案 0 :(得分:2)

不要感觉不好。你所有的问题都是常见的问题。首先,尝试更改

events <- data.frame(comp2,date2,q,stringsAsFactors=FALSE)
早些时候。您的列q正在被隐式转换为一个因子,稍后不允许进行算术* 2操作。

接下来,让我们考虑固定循环

for(i in 1:nrow(events)) {
  events_k <- events[which(comp1==companies[i]),] # data of all event days of company i
  df_k <- df[which(comp2==companies[i]),] # data of all trading days of company i

  for(j in 1:nrow(df_k)) {
    events_k[j, "q"] <-
      if (0 == length(tmp <- df_k[which(days==events_k[j,"date2"]), "ret"] * 2)) NA
      else tmp
  }
  mylist[[i]] <- events_k
}

你的第一个问题是在最后一行,你使用[而不是[[(在R中,前者总是用列表包装,而后者实际访问列表中的值)。

您的第二个问题是有时which(days==events_k[j,"date2"])numeric(0)(即,没有匹配的事件日期)。然后代码会起作用,但您仍然会有很多带有NA的数据帧。要删除它们,您可以执行以下操作:

mylist <- Filter(function(df) nrow(df) > 0,
  lapply(mylist, function(df) df[apply(df, 1, function(row) !all(is.na(row))), ]))

将过滤掉包含空数据框的列表元素,以及数据框中所有NA的行。