如何通过在r中使用循环函数来获得简洁的代码

时间:2016-11-27 13:04:53

标签: r loops

整个数据包括5列,分别命名为A,B,C,D和Portfolio。我将为每个投资组合运行线性回归模型。因此,将整个数据划分为子集数据。然后,运行回归模型并检查其摘要。 数据框如下表所示

      A    B    C    D    Portfolio
1           ...               11
2           ...               22
3           ...               13
4           ...               11
5           ...               21
6           ...               21
7           ...               23
8           ...               12
9           ...               11
10          ...               12 
11          ...               22
...                       

我所做的代码如下所示,

Portfolio_11<-subset(df, Portfolio==11)
Portfolio_12<-subset(df, Portfolio==12)
Portfolio_13<-subset(df, Portfolio==13)
Portfolio_21<-subset(df, Portfolio==21)
Portfolio_22<-subset(df, Portfolio==22)
Portfolio_23<-subset(df, Portfolio==23)

Reg_11<-lm(A ~ B + C + D, data=Portfolio_11)
Reg_12<-lm(A ~ B + C + D, data=Portfolio_12)
Reg_13<-lm(A ~ B + C + D, data=Portfolio_13)
Reg_21<-lm(A ~ B + C + D, data=Portfolio_21)
Reg_22<-lm(A ~ B + C + D, data=Portfolio_22)
Reg_23<-lm(A ~ B + C + D, data=Portfolio_23)

summary(Reg_11)
summary(Reg_12)
summary(Reg_13)
summary(Reg_21)
summary(Reg_22)
summary(Reg_23)

我尝试使用循环函数来简化R代码。像,

for (i=1:3, j=1:3){
Portfolio_ij<-subset(df, Portfolio==ij)
Reg_ij<-lm(A ~ B + C + D, data=Portfolio_ij)
summary(Reg_ij)
}

但是,我是r的首发,并且不太了解循环函数的规则。因此,我想学习它。非常感谢你。

4 个答案:

答案 0 :(得分:2)

我们可以使用其中一个功能组

library(data.table)
dtSummary <- setDT(df)[,  list(list(summary(lm(A ~ B + C + D)))), by = Portfolio]
dtSummary$V1

答案 1 :(得分:1)

为了让自己的生活更轻松,请使用其中一个R包进行数据调整。 Akrun已经提到过data.table;这也是dplyr do的经典用例:

library(dplyr)
df %>%
    group_by(Portfolio) %>%
    do(smry=summary(lm(A ~ B + C + D, data=.)))

答案 2 :(得分:1)

这是split-apply-combine方法的经典案例,或者至少是split-apply部分,因为不清楚你想要对输出做什么。这是在基础R中执行此操作的一种方法,将结果返回到名为Summaries的列表中:

Summaries <- lapply(split(df, df$Portfolio), function(i) summary(lm(A ~ B + C + D, data = i)))

从内部开始,你:

  1. 使用split将原始数据分解为由所需子集组成的列表,此处由DF$Portfolio的唯一值定义。
  2. 使用lapply迭代在步骤1中创建的列表元素上的建模和模型汇总函数。
  3. 结果是一个列表(Summaries),其第i个元素对应于df$Portfolio的第i个子集。方便的是,列表元素的名称与df$Portfolio的唯一值相对应,因此您可以使用Summaries[["21"]]检查它们。或者,如果您只想在终端或降价处看到结果或其他内容,请删除Summaries <-部分。

答案 3 :(得分:0)

使用基数R,您可以尝试:

#creates your combinations
subs <- apply(expand.grid(1:3, 1:2), 1, function(x) as.numeric(paste0(x, collapse="")))
# loop along these combinations. Note the print.
for (i in subs)
   print(summary(lm(A ~ B + C + D, data=subset(df, Portfolio==i))))

但正如评论中所述,一个可重复的例子会有所帮助。

这是一个构建的数据集:

# same as above
subs <- apply(expand.grid(1:3, 1:2), 1, function(x) as.numeric(paste0(x, collapse="")))

# here we create the dataset    
n=50 # we want 50 rows
set.seed(1) # for the sake of reproducibility
df <- data.frame(A=rnorm(n), B=rnorm(n), C=rnorm(n), D=rnorm(n), Portfolio=sample(subs, n, replace=TRUE))

# now we can apply the loop:
for (i in subs){
  cat(rep("*", 20), "\nlm for Portfolio =", i, '\n')  # a cheap console displayer
  print(summary(lm(A ~ B + C + D, data=subset(df, Portfolio==i))))
}

但正如其他人回答data.tabledplyr包时,与基本R相比,会产生更简单/通用的语法。