R Spread功能带有重复项 - 添加瞬态行后仍然无法工作

时间:2016-12-16 15:21:47

标签: r duplicates tidyr spread

尝试让spread()函数与键列中的重复项一起使用 - 是的,之前已经介绍过但我似乎无法使其工作并且我已经花了更多的时间对它的一天(对R来说有点新)。

我有两列数据。第一栏' snowday'代表冬季的第一天,相应的雪深度为“深度”。柱。这是几年的数据(约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

我希望它看起来像这样(列是由&#34; snowday&#34定义的;行值是在不同年份的特定日期记录的各种深度 - 例如天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)中的所有值都是整数。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

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

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

我以一些假数据为例。我们观察3&#34;年&#34;下雪天1和2的数据,但只有2&#34;年&#34;下雪天3和4的数据。

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函数按depth的值分割snowdays,并使用NAs填充短列,最后将所有列cbind填充在一起:

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。在这种情况下,您必须正确定义rowrow第一个下雪日(snowday == 1)应为1,第二个下雪日为2,等等。row第一个第二个下雪天也应为1,第二个下午为2 {2} snowday等。

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