R 中的宽数据到长数据

Nee*_*raj 5 pivot r reshape melt data.table

我在 R 中有以下数据:

structure(list(Name = 1:4, Paper1 = c("C1", "C1", "C1", "C1"), 
Marks1 = 1:4, Paper2 = c("D1", "D1", "D1", "D1"), Marks2 = 1:4, 
Paper3 = c("E1", "E1", "E1", "E1"), Marks3 = 12:15), class = "data.frame", row.names = c(NA, -4L))
Run Code Online (Sandbox Code Playgroud)

我想这样安排我的数据:

structure(list(Name = c(1L, 1L, 1L, 2L, 2L, 2L), Paper = c("C1", 
"D1", "E1", "C1", "D1", "E1"), Marks = c(1L, 1L, 12L, 2L, 2L, 
13L)), class = "data.frame", row.names = c(NA, -6L))
Run Code Online (Sandbox Code Playgroud)

我尝试过shape,,,melt但两者都没有提供所需的输出。请提出解决方案。

sin*_*dur 5

一种选择是melt()

library(data.table)
setDT(df)

melt(
  df, 
  id.vars      = 'Name', 
  measure.vars = patterns('^Paper', '^Marks'),
  value.name   = c('Paper', 'Marks')
)[order(Name), !'variable']

#     Name Paper Marks
#  1:    1    C1     1
#  2:    1    D1     1
#  3:    1    E1    12
#  4:    2    C1     2
#  5:    2    D1     2
#  6:    2    E1    13
#  7:    3    C1     3
#  8:    3    D1     3
#  9:    3    E1    14
# 10:    4    C1     4
# 11:    4    D1     4
# 12:    4    E1    15
Run Code Online (Sandbox Code Playgroud)


har*_*rre 5

对于更短的dplyr选项,我们可以使用pivot_longer-names_sep参数与正则表达式查找周围来分隔数字之前。

\n
library(dplyr)\n\ndf |> \n  pivot_longer(-Name, \n               names_to = c(".value", NA), \n               names_sep = "(?=\\\\d)")\n
Run Code Online (Sandbox Code Playgroud)\n

..或者正如@Allan Cameron 在第五个位置分裂所指出的:names_sep = 5

\n

如果您想保留相应试卷的编号和分数,您可以NA将 中的替换names_to为您想要的列名。

\n

输出:

\n
# A tibble: 12 \xc3\x97 3\n    Name Paper Marks\n   <int> <chr> <int>\n 1     1 C1        1\n 2     1 D1        1\n 3     1 E1       12\n 4     2 C1        2\n 5     2 D1        2\n 6     2 E1       13\n 7     3 C1        3\n 8     3 D1        3\n 9     3 E1       14\n10     4 C1        4\n11     4 D1        4\n12     4 E1       15\n
Run Code Online (Sandbox Code Playgroud)\n