我想使用 for 循环对单个行的元素进行计算。我有两个数据帧
- DF:包含所有交易日股票的数据
- 事件:仅包含股票事件天数的数据
尽管这个特定示例可能有一种更简单的方法,但我想知道如何使用循环中的循环(for-loops)执行此类任务。
首先,我的数据帧:
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 中。最终输出应该是带有"q"列的 data.frame "events",我希望在其中存储计算结果。
# 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 中。任何帮助感谢!!
谢谢!
不要难过。你所有的问题都是常见的R陷阱。首先,尝试更改
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
的行。