【问题标题】:Reshape data table重塑数据表
【发布时间】:2015-09-01 11:19:02
【问题描述】:

我有一个类似的数据表(数据不一定按'col1'排序)

    col0    col1      col2
1:  abc       1         a
2:  abc       2         b 
3:  abc       3         c 
4:  abc       4         d 
5:  abc       5         e
6:  def       1         a
7:  def       2         b 
8:  def       3         c 
9:  def       4         d 
10: def       5         e

我想通过以下方式重塑它

    col0      col1      col2      new_1   new_2   new_3   new_4
1:  abc         1         a         NA      NA       NA      NA
2:  abc         2         b         a       NA       NA      NA
3:  abc         3         c         b       a        NA      NA
4:  abc         4         d         c       b        a       NA 
5:  abc         5         e         d       c        b       a
6:  def         1         a         NA      NA       NA      NA
7:  def         2         b         a       NA       NA      NA
8:  def         3         c         b       a        NA      NA
9:  def         4         d         c       b        a       NA 
10: def         5         e         d       c        b       a

基本上,我想为上述同一行中的每一行获取先前出现的 col2 值,如果没有,则相应的新列应该说 NA。

我当然可以通过在 col2 上合并 5 次来做到这一点,但我需要在一张大桌子上执行此操作(在这种情况下,我将不得不合并 20-30 次)。

在 R 中用 1 行或 2 行实现它的最佳方法是什么?

【问题讨论】:

  • 任何人都可以在不使用开发人员版本的 data.table 的情况下提供不同的解决方案吗?仅使用 CRAN 版本!我

标签: r data.table reshape2


【解决方案1】:

我们可以使用data.table的devel版本的shift,即v1.9.5(安装devel版本的说明是here。默认情况下,shift中的typelag。我们可以将n 指定为向量,在本例中为1:4。我们将输出分配(:=) 到新列。

library(data.table)#v1.9.5+
DT[, paste('new', 1:4, sep="_") := shift(col2, 1:4)]
DT
#   col1 col2 new_1 new_2 new_3 new_4
#1:    1    a    NA    NA    NA    NA
#2:    2    b     a    NA    NA    NA
#3:    3    c     b     a    NA    NA
#4:    4    d     c     b     a    NA
#5:    5    e     d     c     b     a

对于新数据集'DT2',我们需要按'col0'分组,然后在'col2'上执行shift

DT2[, paste('new', 1:4, sep="_") := shift(col2, 1:4), by = col0]
DT2
#   col0 col1 col2 new_1 new_2 new_3 new_4
# 1:  abc    1    a    NA    NA    NA    NA
# 2:  abc    2    b     a    NA    NA    NA
# 3:  abc    3    c     b     a    NA    NA
# 4:  abc    4    d     c     b     a    NA
# 5:  abc    5    e     d     c     b     a
# 6:  def    1    a    NA    NA    NA    NA
# 7:  def    2    b     a    NA    NA    NA
# 8:  def    3    c     b     a    NA    NA
# 9:  def    4    d     c     b     a    NA
#10:  def    5    e     d     c     b     a

数据

df1 <- structure(list(col1 = 1:5, col2 = c("a", "b", "c", "d", "e"), 
new_1 = c(NA, "a", "b", "c", "d"), new_2 = c(NA, NA, "a", 
"b", "c"), new_3 = c(NA, NA, NA, "a", "b"), new_4 = c(NA, 
NA, NA, NA, "a")), .Names = c("col1", "col2", "new_1", "new_2", 
"new_3", "new_4"), class = "data.frame", row.names = c(NA, -5L
))

DT <- as.data.table(df1)

df2 <- structure(list(col0 = c("abc", "abc", "abc", "abc", "abc", 
"def", 
"def", "def", "def", "def"), col1 = c(1L, 2L, 3L, 4L, 5L, 1L, 
2L, 3L, 4L, 5L), col2 = c("a", "b", "c", "d", "e", "a", "b", 
 "c", "d", "e")), .Names = c("col0", "col1", "col2"), 
class = "data.frame", row.names = c(NA, -10L))
DT2 <- as.data.table(df2)

【讨论】:

  • 我不能转移它,因为首先数据不一定是有序的,而且我有不同类别的数据。因此,在转变时,我最终可能会获得其他类别的价值。
  • @user3664020 我不确定您所说的can't shift 是什么意思。我的代码基于您提供的示例。
  • 对问题进行了一些修改。您能否根据新数据修改您的答案?
  • 所以我想做你刚才所做的事情,但对于每个类别的 'col0' 不运行 for 循环或采用蛮力方式。
  • @user3664020 我更新了帖子。检查是否有帮助
猜你喜欢
  • 2015-10-14
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 2013-01-27
  • 2019-11-15
  • 2013-07-21
  • 2015-10-07
相关资源
最近更新 更多