如何实现提取/分离功能(来自dplyr和tidyr)以将一列分为多个列。基于任意值?

时间:2019-02-12 15:57:16

标签: r

我有一列:

Y = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)

我想根据列值的位置分为多个列。例如,我想要:

Y1=c(1,2,3,4,5)
Y2=c(6,7,8,9,10)
Y3=c(11,12,13,14,15)
Y4=c(16,17,18,19,20)

由于我使用的是大数据时间序列集,因此根据一个时间段的长度,划分将是任意的。

3 个答案:

答案 0 :(得分:1)

这不是dplyr解决方案,但我认为最简单的方法将涉及使用矩阵。

foo = function(data, sep.in=5) {
data.matrix = matrix(data,ncol=5)
data.df = as.data.frame(data.matrix)
return(data.df)
}

我尚未对其进行测试,但是此功能应该创建一个data.frame,可以使用cbind()

合并到现有的data.frame中

答案 1 :(得分:1)

您可以使用基数split将此向量拆分为每个长度为5的向量。您还可以使用变量来存储此间隔长度。

repeach = 5一起使用,并以编程方式创建一个序列,可以得到数字1、2,...的序列,其长度除以5(在这种情况下为4) ,每次连续5次。然后split返回向量列表。

值得注意的是,各种SO帖子都建议您将类似的数据存储在诸如此类的列表中,而不是创建多个变量,因此我将其保留在列表形式中。

Y <- 1:20

breaks <- rep(1:(length(Y) / 5), each = 5)
split(Y, breaks)
#> $`1`
#> [1] 1 2 3 4 5
#> 
#> $`2`
#> [1]  6  7  8  9 10
#> 
#> $`3`
#> [1] 11 12 13 14 15
#> 
#> $`4`
#> [1] 16 17 18 19 20

reprex package(v0.2.1)于2019-02-12创建

答案 2 :(得分:0)

我们可以利用split(将注释的代码编写为解决方案)将split vector变成listvector

lst <- split(Y, as.integer(gl(length(Y), 5, length(Y))))
lst
#$`1`
#[1] 1 2 3 4 5

#$`2`
#[1]  6  7  8  9 10

#$`3`
#[1] 11 12 13 14 15

#$`4`
#[1] 16 17 18 19 20

这里,gl通过指定nklength参数来创建分组索引,其中n-给出级别数的整数,k-给出复制次数的整数,length-给出结果长度的整数。

在我们的例子中,我们希望'k'为5。

as.integer(gl(length(Y), 5, length(Y)))
#[1] 1 1 1 1 1 2 2 2 2 2 3 3 3 3 3 4 4 4 4 4

如果要在全局环境中拥有多个对象,请使用list2env

list2env(setNames(lst, paste0("Y", seq_along(lst))), envir = .GlobalEnv)
Y1
#[1] 1 2 3 4 5
Y2
#[1]  6  7  8  9 10
Y3
#[1] 11 12 13 14 15
Y4
#[1] 16 17 18 19 20

或者正如OP在问题中提到的dplyr/tidyr,我们也可以使用这些软件包

library(tidyverse)
tibble(Y) %>%
   group_by(grp = (row_number()-1) %/% 5 + 1) %>% 
   summarise(Y = list(Y)) %>%
   pull(Y)
#[[1]]
#[1] 1 2 3 4 5

#[[2]]
#[1]  6  7  8  9 10

#[[3]]
#[1] 11 12 13 14 15

#[[4]]
#[1] 16 17 18 19 20

数据

Y <- 1:20