问题描述
我有一些来自图像测量的数据,其中列基本上表示位置 (x) 和高度 (z) 数据。问题是这些数据会以宽格式的 .csv 文件形式输出。我试图找到一种方法将其转换为长格式,但我不确定如何执行此操作,因为我无法指定标识符。
我知道有很多关于重塑数据的问题,但我没有找到类似的问题。
举个例子:
df <- data.frame(V1 = c("Profile","x","[m]",2,4,6,8,10,12,NA,NA),V2 = c("1","z",3,9,V3 = c("Profile",V4 = c("2",V5 = c("Profile",14,17),V2 = c("3",1,11,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,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],xci+1]),x = df[-(1:3),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"))))