首页 > 解决方案 > 根据指定变量和标识符的列名收集多个变量

问题描述

我正在处理数据记录器时间序列输出,这些输出具有在不同位置的数据帧内共享的公共环境变量(例如光、温度、风速)。因此,每列首先由被测量的环境变量(例如“a”)命名,然后是其物理位置(例如“1”),并以“_”分隔。

作为一个例子,我们可以想象一个数据框,其中环境变量“a”、“b”和“c”在三个不同的位置同时测量。这给出了日期时间的列名和变量位置的六个独特组合中的每一个,如下所示:

“dt” “a_1” “a_2” “a_3” “b_1” “b_2” “b_3” “c_1” “c_2” “c_3”

我需要将数据框转换为长格式,以便“dt”、“a”、“b”和“c”各有一个列,与每个关联的位置有一个新列“loc”环境变量测量。

下面的代码创建了一个模拟数据框,然后使用一种非常繁琐的方法来创建我想要的输出。但是,此示例代码代码过于繁琐,无法用于大型数据帧(即数十个变量和位置)。

如何通过使用列名中的信息自动转换数据来提高效率,最好是通过 tidyr 和 dplyr 使用 tidyverse 方法?

### Mock data:
start_time <- as.POSIXct("2000-10-01 10:10:10")
df <- data.frame(
    dt= seq.POSIXt(from = start_time, length.out = 100, by = 1),
    a_1=abs(rnorm(100, 1000, 500)),
    b_1=abs(rnorm(100, 35, 5)),
    c_1=abs(rnorm(100, 10, 2.5)),
    a_2=abs(rnorm(100, 1000, 500)),
    b_2=abs(rnorm(100, 35, 5)),
    c_2=abs(rnorm(100, 10, 2.5)),
    a_3=abs(rnorm(100, 1000, 500)),
    b_3=abs(rnorm(100, 35, 5)),
    c_3=abs(rnorm(100, 10, 2.5))
)

### New data frames for each location, with location identifier column:
loc1 <- df %>%
  select(dt, a_1, b_1, c_1) %>%
  rename(a = a_1) %>%
  rename(b = b_1) %>%
  rename(c = c_1) %>%
  mutate(loc = as.character("1"))

loc2 <- df %>%
  select(dt, a_2, b_2, c_2) %>%
  rename(a = a_2) %>%
  rename(b = b_2) %>%
  rename(c = c_2) %>%
  mutate(loc = as.character("2"))

loc3 <- df %>%
  select(dt, a_3, b_3, c_3) %>%
  rename(a = a_3) %>%
  rename(b = b_3) %>%
  rename(c = c_3) %>%
  mutate(loc = as.character("3"))

### Data in desired long format:
all_data_long <- rbind(loc1, loc2, loc3)

标签: rdplyrtidyrdata-manipulation

解决方案


根据要求使用 tidyverse 方法,这对您有用吗?

library(dplyr)
library(tidyr)
out <- df %>% 
  gather(Letter, Val, -dt) %>% 
  separate(Letter, into = c("Letter", "Loc")) %>% 
  spread(Letter, Val)

推荐阅读