我正在尝试从宽数据转换为长数据,但是遇到了特定问题。每个人在旅馆里都有一排房间,但我只知道他们的第一个和最后一个房间。我想填写第一个房间和最后一个房间之间的房间。
data = read.table(text="
name first_room last_room
A 2 5
B 4 7", header=TRUE)
我正在尝试获得每个人的所有房间,包括中间的房间。
我已经尝试过在提德尔中使用Gather,但这只会给我第一个和最后一个房间。
data %>% gather(type, room, -1) %>% arrange(name)
当前输出:
name type room
1 A first_room 2
2 A last_room 5
3 B first_room 4
4 B last_room 7
想要的输出:
Name type room
1 A first_room 2
2 A last_room 3
3 A last_room 4
4 A last_room 5
5 B first_room 4
6 B first_room 5
7 B first_room 6
8 B first_room 7
答案 0 :(得分:3)
一个选项是按“名称”分组之后,从complete
到“房间”的first
元素中依次得到一个last
序列,然后是fill
>
library(tidyverse)
data %>%
gather(type, room, -1) %>%
arrange(name) %>%
group_by(name) %>%
complete(room = seq(room[1], room[2])) %>%
fill(type, .direction = "up")
# A tibble: 8 x 3
# Groups: name [2]
# name room type
# <fct> <int> <chr>
#1 A 2 first_room
#2 A 3 last_room
#3 A 4 last_room
#4 A 5 last_room
#5 B 4 first_room
#6 B 5 last_room
#7 B 6 last_room
#8 B 7 last_room
答案 1 :(得分:1)
这是一种更手动的方法。我可能将akrun的解决方案与complete
一起使用,但这是另一种选择。这在某些方面更普遍...如果您想要类似但不太完整的序列,可以用它做一些更奇怪的事情。
data %>% mutate(room = Map(seq, from = data$first_room, to = data$last_room)) %>%
tidyr::unnest() %>%
select(name, room) %>%
group_by(name) %>%
mutate(type = if_else(row_number() == 1, "first room", "last_room"))
# # A tibble: 8 x 3
# # Groups: name [2]
# name room type
# <fct> <int> <chr>
# 1 A 2 first room
# 2 A 3 last_room
# 3 A 4 last_room
# 4 A 5 last_room
# 5 B 4 first room
# 6 B 5 last_room
# 7 B 6 last_room
# 8 B 7 last_room