簡體   English   中英

選擇多列,然后從寬到長整形

[英]Select multiple columns and reshape wide to long

我擁有與案件及其聯系方式有關的廣泛數據集。 (這是一個虛構的示例;實際數據集要大得多)。

structure(list(record_id = structure(1:4, .Label = c("01-001", 
"01-002", "01-003", "01-004"), class = "factor"), place = structure(c(1L, 
2L, 1L, 1L), .Label = c("a", "b"), class = "factor"), sex = structure(c(2L, 
2L, 1L, 2L), .Label = c("F", "M"), class = "factor"), age = c(4L, 
13L, 28L, 44L), d02_1 = c(2L, 2L, NA, 2L), d02_2 = structure(c(3L, 
2L, 1L, 3L), .Label = c("", "F", "M"), class = "factor"), d02_3 = c(27L, 
16L, NA, 66L), d03_1 = c(3L, 3L, NA, 3L), d03_2 = structure(c(3L, 
3L, 1L, 2L), .Label = c("", "F", "M"), class = "factor"), d03_3 = c(14L, 
55L, NA, 12L), d04_1 = c(4L, NA, NA, NA), d04_2 = structure(c(2L, 
1L, 1L, 1L), .Label = c("", "M"), class = "factor"), d04_3 = c(7L, 
NA, NA, NA)), .Names = c("record_id", "place", "sex", "age", 
"d02_1", "d02_2", "d02_3", "d03_1", "d03_2", "d03_3", "d04_1", 
"d04_2", "d04_3"), row.names = c(NA, -4L), class = "data.frame")

哪里:

  • record_id是案件的唯一標識符
  • 地方是案件存在的地方
  • 年齡是案件的年齡
  • 性是案例的性

  • d02_1,d03_1,d04_1 ... d0j_1是聯系人的ID

  • d02_2,d03_2,d04_2 ... d0j_2是聯系人的性別
  • d02_3,d03_3,d04_3 ... d0j_3是聯系人的年齡

在實際數據集中,每個案例中可能有許多聯系人,並且還有更多與聯系人特征有關的變量。 並非所有案例都有聯系。

我想將數據集重整為整齊的格式,每個案例/聯系人一行,即:

         id case place sex age
1    01-001    1     a   M   4
2  01-001-2    0     a   M  27
3  01-001-3    0     a   M  14
4  01-001-4    0     a   M   7
5    01-002    1     b   M  13
6  01-002-2    0     b   F  16
7  01-002-3    0     b   M  55
8    01-003    1     a   F  28
9    01-004    1     a   M  44
10 01-004-2    0     a   M  66
11 01-004-3    0     a   F  12

我在想,我將需要創建與每個聯系人相關的列名稱的向量(可能在列名稱上使用字符匹配),依次選擇這些列,並將其彼此附加(以及連接大小寫/聯系人ID) ,但確實很難做到沒有很多行代碼的復制。 必須是一種更有效的方法?

這是你想要的?

這是一個dplyr解決方案,出於多種原因,這很丑陋,但我認為它可以完成工作。

DF <- DF %>%
  rename_(.dots=setNames(names(.), gsub('_1','_ContactID',names(.)))) %>%
  rename_(.dots=setNames(names(.), gsub('_2','_sex',names(.)))) %>%
  rename_(.dots=setNames(names(.), gsub('_3','_age',names(.)))) %>%
  rename(d00_sex=sex,d00_age=age) %>%
  mutate(d00_ContactID=1) %>%
  gather(Var,Val,-record_id,-place) %>%
  mutate(Val =ifelse(Val=='',NA,Val)) %>%
  separate(Var,c('ContactLevel','Var'),sep='_') %>%
  spread(Var,Val) %>%
  arrange(record_id,ContactLevel) %>%
  filter(!is.na(age),!is.na(ContactID),!is.na(sex)) %>%
  mutate(age = as.numeric(age))

為了清楚起見,我首先重命名您的變量。 rename_行)

接下來,我將您的案例信息變量放入一個一致的模式,其中案例信息為ContactID = 1。 (對行進行enamemutate

Gather將數據從寬變長,但是卻給我們留下了非常難看的一列,並將您所有的數據轉換為字符。 (這是觸發警告的丑陋部分。)

separate將舊的列名稱拆分為聯系人ID和數據列。

spread然后再次打開年齡,性別和身分證明。 在這一行中,這些數據是您想要的,但是仍然可以進行一些清理。

arrange不是必需的,但是它將所有記錄ID放在一起。

filter也不是必需的,它只刪除沒有合同信息的行。

最后,我使用mutateage從字符轉換為數字。 如果您願意,您也可以在這里將性行為變成一個因素,並可能還會聯系ID。

暫無
暫無

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

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