#r #format
Вопрос:
У меня есть вопрос о преобразовании фрейма данных из широкого формата в длинный формат. Я не нашел никаких решений, которые соответствовали бы моему фрейму данных. У нас было три временных интервала измерения с одними и теми же анкетами (например, PANAS и еще две анкеты). Мой фрейм данных сейчас выглядит так:
| code| PANAS_1| PANAS_2| PANAS1_1| PANAS1_2| PANAS2_1| PANAS2_2|
|CAPQ | 4 | 3 | 1 | 5 | 2 | 4 |
|BANI | 2 | 3 | 4 | 4 | 3 | 2 |
Я хочу поместить его в формат, который выглядит следующим образом:
| code| timeslot| PANAS_1| PANAS_2 |
|CAPQ | 1 | 4 | 3 |
|CAPQ | 2 | 1 | 5 |
|CAPQ | 3 | 2 | 4 |
|BANI | 1 | 2 | 3 |
|BANI | 2 | 4 | 4 |
|BANI | 3 | 3 | 2 |
Я пытался melt()
, но я просто не знаю, что делать, потому что имена переменных в анкетах не совпадают (имена переменных в первом временном интервале просто «PANAS_1», во втором временном интервале начинаются с 1 «PANAS1_1», а в третьем временном интервале начинаются с 2 «PANAS2_1). Кроме того, у меня нет переменной, которая объясняет, в каком состоянии временного интервала находятся элементы.
Я надеюсь, что вы поймете мою проблему и поможете мне ее решить. Если вам нужна дополнительная информация, просто дайте мне знать.
Ответ №1:
Вот используемый подход data.table
. С melt.data.table()
помощью вы можете использовать группы measure.vars. В этом случае вы можете использовать patterns()
для поиска групп по их суффиксу.
library(data.table)
df <- read.table(text = "code| PANAS_1| PANAS_2| PANAS1_1| PANAS1_2| PANAS2_1| PANAS2_2
CAPQ | 4 | 3 | 1 | 5 | 2 | 4
BANI | 2 | 3 | 4 | 4 | 3 | 2
", sep = "|", header = TRUE)
setDT(df)
DT.long <- melt(df,
id.vars = "code",
measure.vars = patterns("_1", "_2"),
variable.name = "timeslot",
value.name = c("PANAS_1", "PANAS_2")
)[order(code), ]
DT.long
#> code timeslot PANAS_1 PANAS_2
#> 1: BANI 1 2 3
#> 2: BANI 2 4 4
#> 3: BANI 3 3 2
#> 4: CAPQ 1 4 3
#> 5: CAPQ 2 1 5
#> 6: CAPQ 3 2 4
Создано 2021-08-19 пакетом reprex (v2.0.1)
Ответ №2:
Вот один из используемых подходов tidyverse
. Вы можете использовать pivot_longer
, чтобы поместить в длинный формат и отделить последнее число после подчеркивания. Затем вы можете добавить timeslot
переменную для каждой code
комбинации /чисел, предполагая, что времена в порядке. Наконец, вы можете вернуться к широкому формату с pivot_wider
(или оставить как есть для дальнейшей обработки/анализа).
library(tidyverse)
df %>%
pivot_longer(cols = -code, names_to = c("var", "PANAS"), names_sep = "_") %>%
group_by(code, PANAS) %>%
mutate(timeslot = 1:n()) %>%
pivot_wider(id_cols = c(code, timeslot), names_from = PANAS, names_prefix = "PANAS_", values_from = value)
Выход
code timeslot PANAS_1 PANAS_2
<chr> <int> <dbl> <dbl>
1 CAPQ 1 4 3
2 CAPQ 2 1 5
3 CAPQ 3 2 4
4 BANI 1 2 3
5 BANI 2 4 4
6 BANI 3 3 2
Кроме того, вы можете переименовать имена столбцов и явно указать время внутри них:
names(df) <- c("code", paste("PANAS", rep(1:3, each = 2), rep(1:2, times = 3), sep = "_"))
df %>%
pivot_longer(cols = -code, names_to = c("timeslot", "PANAS"), names_pattern = "PANAS_(\d )_(\d )") %>%
pivot_wider(id_cols = c(code, timeslot), names_from = PANAS, names_prefix = "PANAS_", values_from = value)