根据模式而不是唯一标识符将数据重塑为长格式

Reshape data to long form based on a pattern and not unique identifier

我有一些来自图像测量的数据,其中列基本上表示位置 (x) 和高度 (z) 数据。问题是这些数据被吐出为宽格式的 .csv 文件。我正在尝试找到一种方法将其转换为长格式,但我不确定该怎么做,因为我无法指定标识符。

我知道有很多关于重塑数据的问题,但我没有找到任何类似的问题。

举个例子:

df <- data.frame(V1 = c("Profile", "x", "[m]", 0, 2, 4, 6, 8, 10, 12, NA, NA),
                 V2 = c("1", "z", "[m]", 3, 3, 4, 10, 12, 9, 2, NA, NA),
                 V3 = c("Profile", "x", "[m]", 0, 2, 4, 6, NA, NA, NA, NA, NA),
                 V4 = c("2", "z", "[m]", 4, 8, 10, 10, NA, NA, NA, NA, NA),
                 V5 = c("Profile", "x", "[m]", 0, 2, 4, 6, 8, 10, 12, 14, 17),
                 V2 = c("3", "z", "[m]", 0, 1, 1, 10, 14, 11, 6, 2, 0))

每两列代表 X、Z 数据(您可以看到按配置文件 1、配置文件 2、配置文件 3 等分组)。但是,测量的长度不相等,因此具有 NA 的行。有没有一种编程方式可以将这些数据重塑为长格式?即:

profile     x     z
Profile 1   0     3
Profile 1   2     3
Profile 1   4     4
...         ...   ...
Profile 2   0     4
Profile 2   2     8
Profile 2   4     10
...         ...   ...

预先感谢您的帮助!

可以按如下方式进行(有点啰嗦,欢迎优化):

  dfcols <- NCOL(df)
  
  xColInds <- seq(1,dfcols,by=2)
  zColInds <- seq(2,dfcols,by=2)
  
  longdata <- do.call("rbind",lapply(1:length(xColInds), function(i) {
    xValInd <- xColInds[i]
    zValInd <- zColInds[i]
    profileName <- paste0(df[1,xValInd]," ",df[1,zValInd])
    xVals <- as.numeric(df[-(1:3),xValInd])
    zVals <- as.numeric(df[-(1:3),zValInd])
    data.frame(profile=rep(profileName,length(xVals)),
               x = xVals,
               z = zVals)
  }))

如果您希望它的性能更高,请不要在每次迭代时都强制转换为 data.frame。最后一个演员就够了,比如:

xColInds <- seq(1,NCOL(df),by=2)
longdataList <- lapply(xColInds, function(xci) {
  list(profileName = paste0(df[1,xci]," ",df[1,xci+1]),
       x = df[-(1:3),xci],
       z = df[-(1:3),xci+1])
})
longdata <- data.frame(profile = rep(unlist(lapply(longdataList,"[[","profileName")),each=NROW(df)-3),
                       x = as.numeric(unlist(lapply(longdataList,"[[","x"))),
                       z = as.numeric(unlist(lapply(longdataList,"[[","z"))))