如何在R中进行迭代?

如何在R中进行迭代?,r,loops,iteration,R,Loops,Iteration,我使用的数据集包含不同时间点相同变量的值。在下面的例子中,我有变量a和b在时间点1和2的值 > set.seed(1) > data <- data.frame(matrix(sample(16), ncol = 4)) > names(data) <- paste(rep(c("a", "b"), each = 2), 1:2, sep = "") > data a1 a2 b1 b2 1 5 3 14 13 2 6 10 1 8 3 9 1

我使用的数据集包含不同时间点相同变量的值。在下面的例子中,我有变量a和b在时间点1和2的值

> set.seed(1)
> data <- data.frame(matrix(sample(16), ncol = 4))
> names(data) <- paste(rep(c("a", "b"), each = 2), 1:2, sep = "")
> data
  a1 a2 b1 b2
1  5  3 14 13
2  6 10  1  8
3  9 11  2  4
4 12 15  7 16
但我知道在R中使用循环是不可行的,我也不知道如何在R中这样的变量名上循环


那么,对于我在R中遇到的问题,什么是正确的解决方案呢?

您可以不用迭代:

data$ab1 <- data$a1 + data$b1
data$ab2 <- data$a2 + data$b2

data$ab1这里有一种方法。我们迭代列名的唯一值,并在这些唯一值与colname值匹配时计算
rowsumes

sapply(unique(sub('\\D', '', names(data))), 
             function(i) rowSums(data[,grepl(i, sub('\\D', '', names(data)))]))
#      1  2
#[1,] 17 23
#[2,] 24 22
#[3,] 14 10
#[4,] 15 11

这将复制您在Stata中使用的相同foreach循环

for(i in 1:2){
  data[, paste("ab", i, sep="")] <- 
    data[,paste("a", i, sep="")] + data[, paste("b", i, sep="")]
}

要以
R
的方式执行此操作

  • 通过
    *apply
    函数使用一些本机迭代
  • 使用内置的
    行和
    (如@Sotos)答案

  • 在DATA框架中使用赋值,即“类似”:您也可以考虑将数据转换为长格式。像这样,它不是整齐的数据,因为列名中有信息。@Heroka我实际上将数据重新格式化为宽格式,因为它似乎更易于操作。但你说得对,这并不整齐,所以我可能会重新考虑一下。你的问题似乎不是关于迭代,而是关于Stata在循环中将变量粘贴到名称中的紧凑语法。(也就是说,
    for(1:2中的i){}
    在R@jaimedash我的Stata解决方案只是一个例子。因为根据R中不推荐的“Internet”循环,我实际上在寻找一个不涉及循环的解决方案,而是其他迭代方式(例如使用应用和/或函数).我知道我可以不用迭代,但我一直在寻找一个更复杂的解决方案(并在其中学到了一些东西).如前所述,我的原始数据集在10个时间点上有大约15个变量的值,因此如果我只是在每个计算中键入,我的R代码将变得相当混乱。好的,对于更复杂的情况,我给出了链接,另一个提示是Heroka给出的:重塑为长格式。(或者在您的情况下:不重塑为宽格式。)我尝试了一个循环,但不知道如何使用这样的循环变量引用列。谢谢!您可以执行
    paste0(…)
    而不是
    paste(…,sep=”“)
    data <- transform(data, ab1=a1+b1, ab2=a2+b2)
    
    sapply(unique(sub('\\D', '', names(data))), 
                 function(i) rowSums(data[,grepl(i, sub('\\D', '', names(data)))]))
    #      1  2
    #[1,] 17 23
    #[2,] 24 22
    #[3,] 14 10
    #[4,] 15 11
    
    for(i in 1:2){
      data[, paste("ab", i, sep="")] <- 
        data[,paste("a", i, sep="")] + data[, paste("b", i, sep="")]
    }
    
    > data
      a1 a2 b1 b2 ab1 ab2
    1 15  1 16 12  31  13
    2 10  7 14  3  24  10
    3  2  5  9  4  11   9
    4  6  8 13 11  19  19
    
    data[paste0('ab', 1:2)] <- sapply(1:2,
                                      function(i)
                                         rowSums(data[paste0(c('a', 'b'), i)]))
    data
    
    #   a1 a2 b1 b2 ab1 ab2
    # 1  5  3 14 13  19  16
    # 2  6 10  1  8   7  18
    # 3  9 11  2  4  11  15
    # 4 12 15  7 16  19  31