簡體   English   中英

使用具有不同命名模式的多列從寬到長重塑

[英]Reshape from wide to long with multiple columns that have different naming patterns

我有一個寬格式的縱向數據集,列數 > 2500。 幾乎所有列都以“W1_”或“W2_”開頭,表示數據收集的波次(即時間點)。 在實際數據中,有 > 2 個波浪。 它們看起來像這樣:

# Populate wide format data frame
person <- c(1, 2, 3, 4)
W1_resp_sex <- c(1, 2, 1, 2)
W2_resp_sex <- c(1, 2, 1, 2)
W1_edu <- c(1, 2, 3, 4)
W2_q_2_1 <- c(0, 1, 1, 0)

wide <- as.data.frame(cbind(person, W1_resp_sex, W2_resp_sex, W1_edu, W2_q_2_1))
wide
#>   person W1_resp_sex W2_resp_sex W1_edu W2_q_2_1
#> 1      1           1           1      1        0
#> 2      2           2           2      2        1
#> 3      3           1           1      3        1
#> 4      4           2           2      4        0

我想從寬格式重塑為長格式,以便數據如下所示:

# Populate long data frame (this is how we want the wide data above to look after reshaping it)
person <- c(1, 1, 2, 2, 3, 3, 4, 4)
wave <- c(1, 2, 1, 2, 1, 2, 1, 2)
sex <- c(1, 1, 2, 2, 1, 1, 2, 2)
education <- c(1, NA, 2, NA, 3, NA, 4, NA)
q_2_1 <- c(NA, 0, NA, 1, NA, 1, NA, 0)

long_goal <- as.data.frame(cbind(person, wave, sex, education, q_2_1))
long_goal
#>   person wave sex education q_2_1
#> 1      1    1   1         1    NA
#> 2      1    2   1        NA     0
#> 3      2    1   2         2    NA
#> 4      2    2   2        NA     1
#> 5      3    1   1         3    NA
#> 6      3    2   1        NA     1
#> 7      4    1   2         4    NA
#> 8      4    2   2        NA     0

為了重塑數據,我嘗試了 pivot_longer()。 我該如何解決這些問題? (我不喜歡使用 data.table。)

  1. 變量具有不同的命名模式(如何正確指定 names_pattern()?)
  2. 多列(查看所有值如何位於“性別”列下)
  3. 當變量只在一個波中收集時創建一個帶有“NA”的列(即,如果它只在第 2 波中收集,我想要一個帶有 W1_varname 的列,其中所有值都是 NA)。
# Re-load wide format data
person <- c(1, 2, 3, 4)
W1_resp_sex <- c(1, 2, 1, 2)
W2_resp_sex <- c(1, 2, 1, 2)
W1_edu <- c(1, 2, 3, 4)
W2_q_2_1 <- c(0, 1, 1, 0)
wide <- as.data.frame(cbind(person, W1_resp_sex, W2_resp_sex, W1_edu, W2_q_2_1))

# Load package
pacman::p_load(tidyr)

# Reshape from wide to long 
long <- wide %>%
  pivot_longer(
    cols = starts_with('W'),
    names_to = 'Wave',
    names_prefix = 'W',
    names_pattern = '(.*)_',
    values_to = 'sex',
    values_drop_na = TRUE
  )
long
#> # A tibble: 16 × 3
#>    person Wave     sex
#>     <dbl> <chr>  <dbl>
#>  1      1 1_resp     1
#>  2      1 2_resp     1
#>  3      1 1          1
#>  4      1 2_q_2      0
#>  5      2 1_resp     2
#>  6      2 2_resp     2
#>  7      2 1          2
#>  8      2 2_q_2      1
#>  9      3 1_resp     1
#> 10      3 2_resp     1
#> 11      3 1          3
#> 12      3 2_q_2      1
#> 13      4 1_resp     2
#> 14      4 2_resp     2
#> 15      4 1          4
#> 16      4 2_q_2      0

代表 package (v2.0.1) 於 2022 年 9 月 19 日創建

我們可以使用pivot_longer重塑為“long”,指定names_pattern以從與 names_to 相同順序匹配的列名( (...) )中捕獲names_to - 即。 wave列將獲得 'W' 之后的數字( \\d+ ),其中.value (列的值)對應於列名中第一個_之后的 ZE83AED3DDF4667DEC0DAAAACB2BB3BE0BZ 。 然后,我們可以通過列名修改resp_sexedu

library(dplyr)
library(tidyr)
pivot_longer(wide, cols = -person, names_to = c("wave", ".value"), 
    names_pattern = "^W(\\d+)_(.*)$") %>%
   rename_with(~ c("sex", "education"), c("resp_sex", "edu"))

-輸出

# A tibble: 8 × 5
  person wave    sex education q_2_1
   <dbl> <chr> <dbl>     <dbl> <dbl>
1      1 1         1         1    NA
2      1 2         1        NA     0
3      2 1         2         2    NA
4      2 2         2        NA     1
5      3 1         1         3    NA
6      3 2         1        NA     1
7      4 1         2         4    NA
8      4 2         2        NA     0

您想要重塑在兩個波中測量的變量。 您可能會發現它們在沒有前綴的namessubstring table找到。

v <- grep(names(which(table(substring(names(wide)[-1], 4)) == 2)), names(wide))
reshape2::melt(data=wide, id.vars=1, measure.vars=v)
#   person    variable value
# 1      1 W1_resp_sex     1
# 2      2 W1_resp_sex     2
# 3      3 W1_resp_sex     1
# 4      4 W1_resp_sex     2
# 5      1 W2_resp_sex     1
# 6      2 W2_resp_sex     2
# 7      3 W2_resp_sex     1
# 8      4 W2_resp_sex     2

暫無
暫無

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

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