For循环替代以在数据帧内枚举

时间:2019-07-22 17:20:46

标签: r

我有一个各种观测值的数据框列表(下面的示例df),我想为新数据框中的每个观测值枚举。

正如标题所示,我尝试了for循环,但是每次迭代花费的时间太长。下面的示例:

flattening <- function(df){
  if(is.null(nrow(df))){
    return(data.frame(temp="foo"))
  } else {
    lengthCheck <- nrow(df)
    dfFlat <- data.frame(matrix(nrow = 0,ncol = 0))
    for(i in 1:lengthCheck){
      dfFlat[1,paste0("id",i)] <- df$id[i]
      dfFlat[1,paste0("date",i)] <- df$date[i]
      dfFlat[1,paste0("purpose",i)] <- df$purpose[i]
      dfFlat[1,paste0("type",i)] <- df$type[i]
    }
    return(dfFlat)
  }
}

示例数据框:

df <- data.frame(id = c(553235,165235,235634),
             date=c("2018-01-01","2018-02-25","2019-03-01"),
             purpose=c("A1","B5","D2"),
             type = c("B","TA","FI"))

结果应为:

     id1      date1 purpose1 type1    id2      date2 purpose2 type2    id3      date3 purpose3 type3
1 553235 2018-01-01       A1     B 165235 2018-02-25       B5    TA 235634 2019-03-01       D2    FI

结果更新:

以下是所有用户建议的微基准测试结果。基准基于10个可变长度数据帧的列表:

Unit: milliseconds
   expr      min       lq     mean   median       uq      max neval cld
    old 22.39654 23.44767 24.62769 24.05926 24.95069 44.71037   100   b
 andrew 15.46494 16.61251 17.91033 17.26803 18.16550 39.40798   100  a 

2 个答案:

答案 0 :(得分:2)

如果您不介意将id变量转换为字符串而不是数字,则可以执行以下操作...

df2 <- as.data.frame(t(as.vector(t(as.matrix(df)))), stringsAsFactors=FALSE)
names(df2) <- outer(names(df),1:nrow(df),paste0)

df2 
     id1      date1 purpose1 type1    id2      date2 purpose2 type2    id3      date3 purpose3 type3
1 553235 2018-01-01       A1     B 165235 2018-02-25       B5    TA 235634 2019-03-01       D2    FI 

这会将您的数据框转换为向量(通过矩阵),并将其设置为新数据框的行,然后使用旧的列名和行号设置列名。

答案 1 :(得分:0)

您可以按以下方式使用foreach并行程序包

foreach(i = 1:lengthCheck, .combine = rbind) %dopar%
{
      dfFlat[1,paste0("id",i)] <- df$id[i]
      dfFlat[1,paste0("date",i)] <- df$date[i]
      dfFlat[1,paste0("purpose",i)] <- df$purpose[i]
      dfFlat[1,paste0("type",i)] <- df$type[i]
}