如何在 J 中将数据数组从宽变长?

How to reshape data array from wide to long in J?

我喜欢在 J 中复制 reshape 功能。

例如,Stata can reshape a dataset "from wide to long". Below is their Example 1 from their documentation:

. use http://www.stata-press.com/data/r11/reshape1.dta

. list
  +-------------------------------------------------------+
  | id   sex   inc80   inc81   inc82   ue80   ue81   ue82 |
  |-------------------------------------------------------|
  |  1     0    5000    5500    6000      0      1      0 |
  |  2     1    2000    2200    3300      1      0      0 |
  |  3     0    3000    2000    1000      0      0      1 |
  +-------------------------------------------------------+

. reshape long inc ue, i(id) j(year)

. list
  +-----------------------------+
  | id   year   sex    inc   ue |
  |-----------------------------|
  |  1     80     0   5000    0 |
  |  1     81     0   5500    1 |
  |  1     82     0   6000    0 |
  |  2     80     1   2000    1 |
  |  2     81     1   2200    0 |
  |  2     82     1   3300    0 |
  |  3     80     0   3000    0 |
  |  3     81     0   2000    0 |
  |  3     82     0   1000    1 |
  +-----------------------------+

注意。 Python Pandas 具有类似的功能 ("stack")。

我了解到J可以导入数据文件(csv格式)如下。

load 'web/gethttp'
] dataset =: gethttp 'https://bbbyc.github.io/reshape1.csv'

load 'tables/csv'
] dataInJArray =: fixcsv dataset

得到这个后我迷路了dataInJArray。我怎样才能重塑它?感谢任何提示/建议!

要使用 J 实际解决您的特定问题,您可以这样做:

NB. t is the data to be stacked:

   [ t=: 3 8 $ 1 0 5000 5500 6000 0 1 0   2 1 2000 2200 3300 1 0 0   3 0 3000 2000 1000 0 0 1 
1 0 5000 5500 6000 0 1 0
2 1 2000 2200 3300 1 0 0
3 0 3000 2000 1000 0 0 1

您可以 select 并适当地组合不同的列

   ({. ,. 1&{ ,. (2 3 4 & {),. (5 6 7 & {))"1 t
1 0 5000 0
1 0 5500 1
1 0 6000 0

2 1 2000 1
2 1 2200 0
2 1 3300 0

3 0 3000 0
3 0 2000 0
3 0 1000 1

由于这会在各组之间留下空白,因此您将 ,/ 应用于整个结果

   ,/@:(({. ,. 1&{ ,. (2 3 4 & {),. (5 6 7 & {))"1) t
1 0 5000 0
1 0 5500 1
1 0 6000 0
2 1 2000 1
2 1 2200 0
2 1 3300 0
3 0 3000 0
3 0 2000 0
3 0 1000 1

我不确定这概括得有多好,但是如果已经适当地组织,可以在包含任意数量记录的表上使用变体。

完成格式化和引入'years'

   [s1=. ,. each <"1  |: s0  NB. years inserted in the next step
+-+-+----+-+
|1|0|5000|0|
|1|0|5500|1|
|1|0|6000|0|
|2|1|2000|1|
|2|1|2200|0|
|2|1|3300|0|
|3|0|3000|0|
|3|0|2000|0|
|3|0|1000|1|
+-+-+----+-+
   [s2=. ({. , ,.@:(9 $ 80 81 82"_); }.)s1  NB. 80 81 82"_ creates a verb that returns 80 81 82 given any argument
+-+--+-+----+-+
|1|80|0|5000|0|
|1|81|0|5500|1|
|1|82|0|6000|0|
|2|80|1|2000|1|
|2|81|1|2200|0|
|2|82|1|3300|0|
|3|80|0|3000|0|
|3|81|0|2000|0|
|3|82|0|1000|1|
+-+--+-+----+-+
   ('id';'year';'sex';'inc';'ue'),:s2
+--+----+---+----+--+
|id|year|sex|inc |ue|
+--+----+---+----+--+
|1 |80  |0  |5000|0 |
|1 |81  |0  |5500|1 |
|1 |82  |0  |6000|0 |
|2 |80  |1  |2000|1 |
|2 |81  |1  |2200|0 |
|2 |82  |1  |3300|0 |
|3 |80  |0  |3000|0 |
|3 |81  |0  |2000|0 |
|3 |82  |0  |1000|1 |
+--+----+---+----+--+