如何在R语言中拆分data.table行列,提取三轴加速度数据?
R语言拆分加速度字符串为三轴数据的解决方案
核心问题分析
你之前用separate_rows出错,是因为这个函数会把每行的120个数值拆成120行,后续直接用mutate+seq时,生成的序列长度和当前分组不匹配——seq是按整个数据集的行数生成,而非每个原ID/timestamp组内的索引,自然触发长度错误。
下面提供几种高效的解决方法,优先适配你用的data.table,也包含dplyr的正确用法:
方法一:data.table原生操作(推荐,效率更高)
利用data.table的逐行处理特性,直接在每行内拆分字符串并提取三轴数据:
library(data.table) # 假设你的数据对象是dt dt[, acceleration_vec := lapply(acceleration_raw, function(x) as.numeric(strsplit(x, "\\s+")[[1]]))] # 提取三轴数据:acc_x取1,4,7...;acc_y取2,5,8...;acc_z取3,6,9... dt[, `:=`( acc_x = lapply(acceleration_vec, function(v) v[seq(1, 120, 3)]), acc_y = lapply(acceleration_vec, function(v) v[seq(2, 120, 3)]), acc_z = lapply(acceleration_vec, function(v) v[seq(3, 120, 3)]) )][, acceleration_vec := NULL] # 删除中间临时列
如果需要把每个轴的40个数值展开成多行(原一行变40行,每行对应一个测量点的三轴数据),可以用unlist:
dt_long <- dt[, .( ID, timestamp, acc_x = unlist(acc_x), acc_y = unlist(acc_y), acc_z = unlist(acc_z) )]
方法二:dplyr正确处理方式
如果偏好dplyr语法,用rowwise实现逐行处理,避免拆分后索引不匹配的问题:
library(dplyr) library(tidyr) # 保留宽格式(每个轴是列表列,存40个数值) dt_processed <- dt %>% rowwise() %>% mutate( acc_vec = list(as.numeric(strsplit(acceleration_raw, "\\s+")[[1]]), acc_x = list(acc_vec[seq(1, 120, 3)]), acc_y = list(acc_vec[seq(2, 120, 3)]), acc_z = list(acc_vec[seq(3, 120, 3)]) ) %>% ungroup() %>% select(-acceleration_raw, -acc_vec) # 转长格式(展开成40行/原行) dt_long <- dt_processed %>% unnest(c(acc_x, acc_y, acc_z))
方法三:修正separate_rows的错误用法
如果你一定要用separate_rows,必须先按原ID和timestamp分组,生成组内索引后再筛选三轴数据:
library(dplyr) library(tidyr) dt %>% separate_rows(acceleration_raw, sep = "\\s+", convert = TRUE) %>% group_by(ID, timestamp) %>% mutate( idx = row_number(), # 根据索引模3判断所属轴 axis = case_when( idx %% 3 == 1 ~ "acc_x", idx %% 3 == 2 ~ "acc_y", idx %% 3 == 0 ~ "acc_z" ) ) %>% pivot_wider(names_from = axis, values_from = acceleration_raw) %>% group_by(ID, timestamp) %>% mutate(measurement_id = row_number()) %>% # 添加测量点编号 ungroup()
内容的提问来源于stack exchange,提问作者helianthus
相关产品推荐
相关产品推荐

