我正在处理3D动作捕捉数据。这意味着对于身体中的几个关节,我有3列(X,Y,Z)的关节坐标(例如,描述左膝关节中心位置的三列是:LKX,LKY,LKZ)。
我的最终目标是至少绘制9个联合中心,我相信实现这一目标的唯一方法是将我的宽幅数据帧转换为长数据帧。
正如你所知,我试图改变以X:Y或Z结尾的许多联合中心集。因此,我尝试在tidyr:extract中使用正则表达式,但我无法正确使用代码
df_wide <- data.frame(
ID = rep(1:2, each=10),
JN = rep(1:2, each=5),
Frame = rep(1:5, 4),
System = rep(1:2, 10),
RKX = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
RKY = rep(1:10+rnorm(10,mean=1,sd=0.5),2),
RKZ = rep(1:10+rnorm(10,mean=1,sd=0.5), 2),
LHeX = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
LHeY = rep(1:10-rnorm(10,mean=1,sd=0.5),2),
LHeZ = rep(1:10-rnorm(10,mean=1,sd=0.5),2))
head(df_wide, 2)
ID JN Frame System RKX RKY RKZ LHeX LHeY LHeZ
1 1 1 1 1 1.332827 2.068720 2.295742 -0.02336031 -0.3011227 -1.212326
2 1 1 2 2 3.570076 3.306799 3.136177 2.08828231 1.9226740 2.106496
我希望得到这个结果:
ID JN Frame System joint X Y Z
1 1 1 1 1 RK 1.440103 2.221676 1.621871
2 1 1 1 1 LHe 3.537940 3.060948 2.856955
这是我最近的(很多)尝试。它有两个问题; 1)提取物仅产生NA; 2)spread返回“错误:行的重复标识符”我怀疑这与提取问题有关。
df_3D <- df_wide %>%
gather(keys, values, -ID, -JN, -Frame, -System)%>%
extract(keys, c("X", "Y", "Z", "joint"), "(X$) (Y$) (Z$) ([A-Z].$)")%>%
spread(X, values)
我找到了几个关于转换的好问题和答案,但没有一个专门针对正则表达式的使用。
答案 0 :(得分:4)
你的方法有点偏差。收集后keys
列的每个元素都具有结构<Joint><Coord>
,因此您需要以下内容:
df_wide %>%
gather(keys, values, -ID, -JN, -Frame, -System) %>%
extract(keys, c("Joint", "Coord"), "(.*)(X|Y|Z)$") %>%
spread(Coord, values)
我在这里使用的正则表达式捕获了第一组中的任何内容(因为我不知道所有可能的联名),然后X或Y或Z作为第二组中的最后一个字符。还有很多其他的正则表达式可以达到同样的效果。
输出:
ID JN Frame System Joint X Y Z
1 1 1 1 1 LHe 0.1344259 -0.2927277 0.05375166
2 1 1 1 1 RK 1.8083539 2.4053498 2.32899399
3 1 1 2 2 LHe 1.1777492 1.1780538 0.96549849
4 1 1 2 2 RK 3.2254236 2.4100235 2.79816371
答案 1 :(得分:2)
您需要将数据收集为超长格式,然后拆分维度,然后将数据传播回X,Y和Z列:
library(tidyr)
library(stringr)
df2 <- df_wide %>%
# leave the other columns
gather( jointid, position, -ID, -JN, -Frame, -System ) %>%
# insert a seperator to make it easier to split the X/Y/Z from the joint name
mutate(jointid = str_replace( jointid, "X|Y|Z", ";\\0")) %>%
# split the joint name and the dimension apart
tidyr::separate(jointid, c('joint', 'dim'), sep = ";" ) %>%
# spread the joint and position apart into 3 columns
spread(dim, position)