0

试图让 spread() 函数与键列中的重复项一起工作 - 是的,这已经被覆盖过,但我似乎无法让它工作,我花了一天的大部分时间在它上面(有点R 的新手)。

我有两列数据。第一列“下雪日”代表冬季的第一天,“深度”列中对应的积雪深度。这是几年的数据(约 62 年)。因此,下雪天列应该有六十二年的第一、第二、第三等天——这会在下雪天产生重复:

    snowday row depth
       1   1     0
       1   2     0
       1   3     0
       1   4     0
       1   5     0
       1   6     0
...

      75 4633    24
      75 4634     4
      75 4635     6
      75 4636    20
      75 4637    29
      75 4638     1

我添加了一个“行”列以使数据框更加瞬态(我隐约理解为 1:4638 行是每年 75 天在约 62 年中进行的总测量值。现在我想传播它宽的:

wide <- spread(seasondata, key = snowday, value =  depth, fill = 0)

我全为零:

row 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
 1 0 0 0 0 0 0 0 0 0  0  0   0  0 0
 2 0 0 0 0 0 0 0 0 0  0  0   0  0 0
 3 0 0 0 0 0 0 0 0 0  0  0   0  0 0

我希望它看起来像这样(列由“下雪天”定义,行值是在不同年份记录的特定日期的各种深度 - 例如第 1 天到第 11 天:

   1 2 3 4 5 6 7 8 9 10 11 12 13 14 
   2 1 3 4 0 0 1 0 2  8  9 19  0 3
   0 8 0 0 0 4 0 6 6  0  1  0  2 0
   3 5 0 0 0 2 0 1 0  2  7  0 12 4

我想我在这里基本上遗漏了一些东西——我尝试过通过 drop=TRUE 或 convert = TRUE 工作,输出值要么全为零,要么全是 NA,这取决于我如何修补。此外,data.frame(seasondata) 中的所有值都是整数。有什么想法吗?

4

1 回答 1

0

在我看来,您想要做的是depth根据 的值拆分列snowday,然后将所有 75 列绑定在一起。

有一个复杂性,因为 62*75 不是 4638,所以我假设我们在某些年份不会观察到 75 个下雪天。也就是说,75 个列(下雪天)中的某些列将没有 62 个观测值。NA我们将通过用s填充短列来确保所有 75 列都是 62 个条目。

我做一些假数据作为例子。我们观察到下雪天 1 和 2 的 3 个“年”数据,但下雪天 3 和 4 的数据只有 2 个“年”。

set.seed(1)
seasondata <- data.frame(
  snowday = c(rep(1:2, each = 3), rep(3:4, each = 2)),
  depth = round(runif(10, 0, 10), 0))
#    snowday depth
# 1        1     3
# 2        1     4
# 3        1     6
# 4        2     9
# 5        2     2
# 6        2     9
# 7        3     9
# 8        3     7
# 9        4     6
# 10       4     1

我们首先弄清楚一列应该有多长。在你的情况下,m == 62. 在我的例子中,m == 3(数据的年份)。

m <- max(table(seasondata$snowday))

现在,我们使用该函数按 的值by进行拆分,并用 NA 填充短列,最后将所有列一起填充:depthsnowdayscbind

out <- do.call(cbind, 
  by(seasondata$depth, seasondata$snowday,
    function(x) {
      c(x, rep(NA, m - length(x)))
    }
  )
)
out
#      1 2  3  4
# [1,] 3 9  9  6
# [2,] 4 2  7  1
# [3,] 6 9 NA NA

使用spread

spread如果你愿意,你可以使用。在这种情况下,您必须row正确定义。row第一个下雪天应为 1 ( snowday == 1),第二个下雪天row应为 2,以此类推。第一个第二个下雪天应为 1,第二个第二个下雪天应为 2,以此类推。

seasondata$row <- unlist(sapply(rle(seasondata$snowday)$lengths, seq_len))
seasondata
#    snowday depth row
# 1        1     3   1
# 2        1     4   2
# 3        1     6   3
# 4        2     9   1
# 5        2     2   2
# 6        2     9   3
# 7        3     9   1
# 8        3     7   2
# 9        4     6   1
# 10       4     1   2

现在我们可以使用spread

library(tidyr)
spread(seasondata, key = snowday, value = depth, fill = NA)
#   row 1 2  3  4
# 1   1 3 9  9  6
# 2   2 4 2  7  1
# 3   3 6 9 NA NA
于 2016-12-17T05:17:23.443 回答