使用 pivot_longer 从电子表格中重组具有多列的宽数据

Using pivot_longer to restructure wide data, with multiple columns, from a spreadsheet

我确定有这个问题的答案,但我找不到。我已经尝试使用几个 R 函数的几个解决方案,包括 reshape、gather 和 pivot_longer。我的问题是数据来自具有多列的电子表格。我将尝试展示电子表格的示例:

全名 SOCW725 SOCW748 SOCW799 平均 SOCW725 SOCW752 SOCW782 平均 SOCW725 SOCW748 SOCW752 平均
比维斯 B 3.5 3.22 2.56 3.07 2.33 3.33 4.2 3.5 3.33 3.23 无数据 3.00
El Guapo 3.25 3.02 2.75 3.18 3.33 4.33 4.15 2.25 2.67 3.42 4 2.44

实际数据文件要宽得多。每组三门课程(例如,SOCW725、SOCW748、SOCW799)代表一种能力,共有九种能力。我将它们从 table 中删除,因为我相信一旦我弄清楚了(我希望),我就可以将它们插入到数据框中。因此,我试图将 pivot_longer 分为三列(添加 CompetencyID 后将为 4)。这些列是:名称、课程和评级。我不需要平均值,因为我可以重新计算它。以下是我使用的代码示例:

d1 <- pivot_longer(my_data, 
               cols = !1, 
               names_to = "Course",
               values_to = "Ratings",
               )

这可行,但重复的行名(即课程名称)有一个 .后跟一个数字(例如,SOCW725.1、SOCW725.2 等)。我明白为什么,但我不知道如何摆脱它。我可能可以弄清楚如何从结果中编辑 .#,但想找到一种使用 dplyr::pivot_table.

的更快方法

提前谢谢你。

如果我们有兴趣在单列中返回 'FullName' 和 'SOCW' 列(重复),select 感兴趣的列,然后使用 pivot_longer names_pattern 作为 ".value" 并从不带 . ([^.]+) 后跟数字的列名称中捕获子字符串。

library(dplyr)
library(tidyr)
my_data %>% 
    select(FullName, starts_with("SOCW")) %>% 
    pivot_longer(cols = starts_with("SOCW"), names_to = ".value", 
         names_pattern = '^(SOCW[^.]+)')
# A tibble: 6 x 6
  FullName SOCW725 SOCW748 SOCW799 SOCW752 SOCW782
  <chr>      <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1 Beavis B    3.5     3.22    2.56    3.33    4.2 
2 Beavis B    2.33    3.23   NA      NA      NA   
3 Beavis B    3.33   NA      NA      NA      NA   
4 El Guapo    3.25    3.02    2.75    4.33    4.15
5 El Guapo    3.33    3.42   NA       4      NA   
6 El Guapo    2.67   NA      NA      NA      NA  

data.frame 默认情况下不允许重复的列名。它使用 make.unique 通过为每个重复附加 .1.2 等来修改列名。


如果我们只需要三列

library(stringr)
my_data %>% 
   select(FullName, starts_with("SOCW")) %>% 
   pivot_longer(cols = starts_with("SOCW")) %>% 
   mutate(name = str_remove(name, "\.\d+$"))
# A tibble: 18 x 3
   FullName name    value
   <chr>    <chr>   <dbl>
 1 Beavis B SOCW725  3.5 
 2 Beavis B SOCW748  3.22
 3 Beavis B SOCW799  2.56
 4 Beavis B SOCW725  2.33
 5 Beavis B SOCW752  3.33
 6 Beavis B SOCW782  4.2 
 7 Beavis B SOCW725  3.33
 8 Beavis B SOCW748  3.23
 9 Beavis B SOCW752 NA   
10 El Guapo SOCW725  3.25
11 El Guapo SOCW748  3.02
12 El Guapo SOCW799  2.75
13 El Guapo SOCW725  3.33
14 El Guapo SOCW752  4.33
15 El Guapo SOCW782  4.15
16 El Guapo SOCW725  2.67
17 El Guapo SOCW748  3.42
18 El Guapo SOCW752  4   

数据

my_data <- structure(list(FullName = c("Beavis B", "El Guapo"), SOCW725 = c(3.5, 
3.25), SOCW748 = c(3.22, 3.02), SOCW799 = c(2.56, 2.75), Average = c(3.07, 
3.18), SOCW725.1 = c(2.33, 3.33), SOCW752 = c(3.33, 4.33), SOCW782 = c(4.2, 
4.15), Average.1 = c(3.5, 2.25), SOCW725.2 = c(3.33, 2.67), SOCW748.1 = c(3.23, 
3.42), SOCW752.1 = c(NA, 4L), Average.2 = c(3, 2.44)),
 class = "data.frame", row.names = c(NA, 
-2L))

在您的帮助下 akrun,我能够使用它:

d1 <- pivot_longer(my_data, 
                    cols = !1, 
                    names_to = "Course",
                    values_to = "Ratings",
                    names_pattern = '^(SOCW[^.]+)'
                    )

正则表达式在我的学习清单上。