在 R 中从宽到长重塑数据框
Reshaping a data frame from wide to long in R
我有以下数据框,其中包含来自 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) dplyr/tidyr 使用gather
将df
转换为长格式,然后用下划线分隔生成的variable
列分成两列。最后根据 variable
列(包含字符串 pressure
和 temperature
和 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
有固定的列,那么我们可以通过硬编码 varying
和 sensors
来简化上面的代码,使用这些定义来代替上面更复杂但通用的代码:
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))
我有以下数据框,其中包含来自 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) dplyr/tidyr 使用gather
将df
转换为长格式,然后用下划线分隔生成的variable
列分成两列。最后根据 variable
列(包含字符串 pressure
和 temperature
和 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
有固定的列,那么我们可以通过硬编码 varying
和 sensors
来简化上面的代码,使用这些定义来代替上面更复杂但通用的代码:
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))