更高级的 groupby 操作和争吵以制作新的数据框

A more advanced groupby operation and wrangling to make a new dataframe

我在创建和重新排列数据集时遇到了问题。这种争论对我来说太高级了,我真的很感谢你在这方面的帮助。如果这可以用 dplyr 来完成,那就太好了。我在下面创建了一个问题示例:my df:

     vehicle  color  a  b  c  d  A1  A2  A3  B1  B2  B3  C1  C2  C3  D1  D2  D3
resp                                                                           
1       bike  green  5  4  1  3   3   4   5   3   5   3 NaN NaN NaN NaN NaN NaN
2       walk    red  5  3  3  3   4   5   3   3   5   4 NaN NaN NaN NaN NaN NaN
3        car  green  4  2  3  3   4   3   5   4   5   5 NaN NaN NaN NaN NaN NaN
4        car   blue  4  5  4  4 NaN NaN NaN NaN NaN NaN   5   5   5   3   3   4
5        bus  black  2  4  4  3 NaN NaN NaN   2   3   3   2   2   1 NaN NaN NaN
6        car    red  4  2  3  3   3   4   4 NaN NaN NaN   4   4   4 NaN NaN NaN
7        bus   blue  5  5  2  3   3   3   5   4   3   2 NaN NaN NaN NaN NaN NaN
8       walk    red  3  3  4  3 NaN NaN NaN   5   5   5   5   3   3 NaN NaN NaN
9        car   blue  5  3  4  3   3   3   3 NaN NaN NaN   4   3   4 NaN NaN NaN

数据集包含受访者和问题的答案。我想做的是制作一个新的数据框,以 resp 作为索引,并根据受访者的回答方式重新排列数据。 a、b、c、d、车辆和颜色列中的数据在新数据框中为受访者堆叠(希望这是表达它的正确方式)。此外,A 到 C 列的值位于 BL_val 列下的新框架中。只填大写字母(A1-D3)到小写字母(a,b,c,d)对应的数据,其余为NAN

我想从中创建一个新的数据框,它应该如下所示:

ds:

     vehicle  color sl  sl_val  BL_val1  BL_val2  BL_val3
resp                                                     
1       bike  green  a       5        3        4        5
1       bike  green  b       4        3        5        3
1       bike  green  c       1      NaN      NaN      NaN
1       bike  green  d       3      NaN      NaN      NaN
2       walk    red  a       5        4        5        3
2       walk    red  b       3        3        5        4
2       walk    red  c       3      NaN      NaN      NaN
2       walk    red  d       3      NaN      NaN      NaN
3        car  green  a       4        4        3        5
3        car  green  b       2        4        5        5
3        car  green  c       3      NaN      NaN      NaN
3        car  green  d       3      NaN      NaN      NaN
4        car   blue  a       4      NaN      NaN      NaN
4        car   blue  b       5      NaN      NaN      NaN
4        car   blue  c       4        5        5        5
4        car   blue  d       4        3        3        4
5        bus  black  a       2      NaN      NaN      NaN
5        bus  black  b       4        2        3        3
5        bus  black  c       4        2        2        1
5        bus  black  d       3      NaN      NaN      NaN
6        car    red  a       4        3        4        4
6        car    red  b       2      NaN      NaN      NaN
6        car    red  c       3        4        4        4
6        car    red  d       3      NaN      NaN      NaN
7        bus   blue  a       5        3        3        5
7        bus   blue  b       5        4        3        2
7        bus   blue  c       2      NaN      NaN      NaN
7        bus   blue  d       3      NaN      NaN      NaN
8       walk    red  a       3      NaN      NaN      NaN
8       walk    red  b       3        5        5        5
8       walk    red  c       4        5        3        3
8       walk    red  d       3      NaN      NaN      NaN
9        car   blue  a       5        3        3        3
9        car   blue  b       3      NaN      NaN      NaN
9        car   blue  c       4        4        3        4
9        car   blue  d     NaN      NaN      NaN      NaN

我真的需要一些帮助,我想不通!!

data.table v1.9.6:

require(data.table) # v1.9.6+
ans = melt(setDT(df), measure=patterns("^[abcd]$", "1$", "2$", "3$"), 
         variable.name="sl", value.name = c("sl_val", paste0("BL_val", 1:3)))
setattr(ans$sl, 'levels', letters[1:4])
setorder(ans, resp)

data.table 的 melt 函数接受 measure.vars 的列表并将它们中的每一个组合到一个单独的列中。从那里开始,剩下的就是相应地设置 levels,然后按 resp 重新排序 data.table

请参阅 this post for advantages of setorder. See Efficient reshaping using data.tables vignette and my UseR'15 talk 以了解有关使用 data.table 重塑的更多信息。