簡體   English   中英

R:基於其他21列的集合/展開/重塑21列

[英]R: Gather/Spread/Reshape 21 Columns Based on 21 Other Column s

我想基於某些字段中的值創建列,並由其他字段中的值填充。 例如,column1_time的值為“ 1030”,column1_status的值為“ booked”。 我想將它們轉到具有“已預訂”值的新字段time1030中。 有21個具有時間的唯一列(時間每行僅列出一次,因此它們在21列中是唯一的)-還有21個唯一的列,其狀態映射回時間列。 因此,這42個時間+狀態列應在每個唯一時間重新排列為一列,並以該時間的相應狀態填充。

我有看起來像這樣的數據:

在此處輸入圖片說明

我想利用R的collect / spread或reshape2(舊版)功能來轉置此數據,使其看起來像這樣: 在此處輸入圖片說明

我在gatherspread進行了幾個小時的修改,但無法弄清楚。 我以為將鍵設置為ends_with('_time') ,將值設置為ends_with('_status')可能可行,但是我的嘗試卻沒有。

有關數據的可重現示例:

structure(list(appointment1_time = c("1030", "1030"), appointment2_time = c("1100", 
"1100"), appointment3_time = c("1130", "1130"), appointment4_time = c("1200", 
"1200"), appointment5_time = c("1230", "1230"), appointment6_time = c("0100", 
"0100"), appointment7_time = c("0130", "0130"), appointment8_time = c("0200", 
"0200"), appointment9_time = c("0230", "0230"), appointment10_time = c("0300", 
"0300"), appointment11_time = c("0330", "0330"), appointment12_time = c("0400", 
"0400"), appointment13_time = c("0430", "0430"), appointment14_time = c("0500", 
"0500"), appointment15_time = c("0530", "0530"), appointment16_time = c("0600", 
""), appointment17_time = c("0630", ""), appointment18_time = c("0700", 
""), appointment19_time = c("0730", ""), appointment20_time = c(NA_character_, 
NA_character_), appointment21_time = c(NA_character_, NA_character_
), appointment1_status = c("booked", "available"), appointment2_status = c("booked", 
"available"), appointment3_status = c("booked", "available"), 
    appointment4_status = c("booked", "available"), appointment5_status = c("booked", 
    "available"), appointment6_status = c("booked", "available"
    ), appointment7_status = c("booked", "available"), appointment8_status = c("booked", 
    "available"), appointment9_status = c("booked", "available"
    ), appointment10_status = c("booked", "available"), appointment11_status = c("booked", 
    "available"), appointment12_status = c("available", "available"
    ), appointment13_status = c("available", "available"), appointment14_status = c("available", 
    "available"), appointment15_status = c("booked", "available"
    ), appointment16_status = c("available", ""), appointment17_status = c("available", 
    ""), appointment18_status = c("available", ""), appointment19_status = c("available", 
    ""), appointment20_status = c(NA_character_, NA_character_
    ), appointment21_status = c(NA_character_, NA_character_)), row.names = 1:2, class = "data.frame")

使用tidyverse的解決方案。

library(tidyverse)

# Get the time order
ord <- dat %>% select(ends_with("time")) %>% slice(1) %>% unlist()
# Remove NA
ord <- ord[!is.na(ord)]

dat2 <- dat %>%
  rowid_to_column() %>%
  gather(Column, Value, -rowid) %>%
  separate(Column, into = c("Apt", "time/status"), sep = "_") %>%
  spread(`time/status`, Value) %>%
  # Remove NA or "" in the status column
  filter(!is.na(status) & !status %in% "") %>%
  mutate(Apt = str_c("apt_slot", time, sep = "_")) %>%
  select(-time) %>%
  spread(Apt, status) %>%
  select(-rowid) %>%
  # Reorder the column
  select(str_c("apt_slot", ord, sep = "_"))

dat2
# apt_slot_1030 apt_slot_1100 apt_slot_1130 apt_slot_1200 apt_slot_1230 apt_slot_0100 apt_slot_0130
# 1        booked        booked        booked        booked        booked        booked        booked
# 2     available     available     available     available     available     available     available
# apt_slot_0200 apt_slot_0230 apt_slot_0300 apt_slot_0330 apt_slot_0400 apt_slot_0430 apt_slot_0500
# 1        booked        booked        booked        booked     available     available     available
# 2     available     available     available     available     available     available     available
# apt_slot_0530 apt_slot_0600 apt_slot_0630 apt_slot_0700 apt_slot_0730
# 1        booked     available     available     available     available
# 2     available          <NA>          <NA>          <NA>          <NA>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM