在R中将数据帧从宽到长整形

时间:2015-11-22 00:11:14

标签: r reshape reshape2

我有以下数据框,包含来自3个传感器的温度和压力数据:

df <- data.frame(
         Test = 1:10, 
         temperature_sensor1=rnorm(10,25,5), 
         temperature_sensor2 = rnorm(10,25,5), 
         temperature_sensor1 = rnorm(10,25,5), 
         pressure_sensor1 = rnorm(10,10,2),
         pressure_sensor2 = rnorm(10,10,2), 
         pressure_sensor3 = rnorm(10,10,2))

如何将其重新整形为长格式,以便每行具有单个传感器的温度和压力数据

Test Sensor Temperature Pressure

谢谢!

1 个答案:

答案 0 :(得分:2)

以下是两种方法:

1)dplyr / tidyr 使用dfgather转换为长格式,然后将生成的variable列用下划线分隔为两列。最后根据variable列(包含字符串pressuretemperature以及value列(包含数字)从长到宽转换:

library(dplyr)
library(tidyr)
df %>% 
   gather("variable", "value", -Test) %>% 
   separate(variable, c("variable", "sensor"), sep = "_") %>%
   spread(variable, value)

2)可以使用reshape。不需要包裹。标记为可选的行将删除行名称。如果这无关紧要,可以省略。

unames <- grep("_", names(df), value = TRUE)

varying <- split(unames, sub("_.*", "", unames))
sensors <- unique(sub(".*_", "", unames))

long <- reshape(df, dir = "long", varying = varying, v.names = names(varying),
         times = sensors, timevar = "sensor")
rownames(long) <- NULL # optional

如果df有固定列,那么我们可以通过硬编码varyingsensors来使用这些定义代替上面更复杂但通用的代码来简化上述内容:

varying <- list(pressure = 2:4, temperature = 5:7)
sensors <- c("sensor1", "sensor2", "sensor3")

注意:要重复创建df,我们必须首先设置种子,因为使用了随机数,所以我们确定df就像这样。另请注意,问题temperature_sensor1在两列上使用,我们假设第二次出现的目的是temperature_sensor3

set.seed(123)
df <- data.frame(
         Test = 1:10, 
         temperature_sensor1=rnorm(10,25,5), 
         temperature_sensor2 = rnorm(10,25,5), 
         temperature_sensor3 = rnorm(10,25,5), 
         pressure_sensor1 = rnorm(10,10,2),
         pressure_sensor2 = rnorm(10,10,2), 
         pressure_sensor3 = rnorm(10,10,2))