重复记录N次,并创建一个从1到N的新序列

时间:2017-07-29 06:32:46

标签: r

我想重复data.frame的行N次。这里N基于data.frame的每一行中的第一列和第二列的值之间的差来计算。在这里,我面临着N的问题。特别是,N可能每行都有变化。我需要通过增加K来创建一个新列,从第1行的第一个值到第二个值创建一个序列。这里K对所有行保持不变。

Ex: d1<-data.frame(A=c(2,4,6,8,1),B=c(8,6,7,8,10))

在上面的数据集中,共有5行。第一行中第一个和第二个值之间的差异是7.现在我需要复制第一行7次,并且需要创建一个序列为2,3,4,5,6,7和8的新列。 / p>

我可以使用以下代码创建数据集。

dist<-1
rec_len<-c()
seqe<-c()
for(i in 1:nrow(d1))
{
    a<-seq(d1[i,"A"],d1[i,"B"],by=dist)
    rec_len<-c(rec_len,length(a))
    seqe<-c(seqe,a)
}
d1$C<-rec_len

d1<-d1[rep(1:nrow(d1),d1$C),]
d1$D<-seqe
row.names(d1)<-NULL

但这需要很长时间。是否有可能加快这一进程?

4 个答案:

答案 0 :(得分:3)

data.table方法可以使用1:nrow(df)作为分组变量来进行逐行操作,以创建包含A和B序列的列表,然后取消列表,即

library(data.table)

setDT(d1)[, C := B - A + 1][, 
     D := list(list(seq(A, B))), by = 1:nrow(d1)][, 
                lapply(.SD, unlist), by = 1:nrow(d1)][, 
                                              nrow := NULL][]

由此给出,

   A  B  C  D
 1: 2  8  7  2
 2: 2  8  7  3
 3: 2  8  7  4
 4: 2  8  7  5
 5: 2  8  7  6
 6: 2  8  7  7
 7: 2  8  7  8
 8: 4  6  3  4
 9: 4  6  3  5
10: 4  6  3  6
11: 6  7  2  6
12: 6  7  2  7
13: 8  8  1  8
14: 1 10 10  1
15: 1 10 10  2
16: 1 10 10  3
17: 1 10 10  4
18: 1 10 10  5
19: 1 10 10  6
20: 1 10 10  7
21: 1 10 10  8
22: 1 10 10  9
23: 1 10 10 10
    A  B  C  D

注意您可以在K内轻松更改seq,即

setDT(d1)[, C := B - A + 1][, 
     D := list(list(seq(A, B, by = 0.2))), by = 1:nrow(d1)][, 
                lapply(.SD, unlist), by = 1:nrow(d1)][, 
                                              nrow := NULL][]

答案 1 :(得分:2)

您可以使用列表和purr包来处理数据框的每一行:

data.frame(A=c(2,4,6,8,1),B=c(8,6,7,8,10)) %>%   # take original data frame
  setNames(c("from", "to")) %>% pmap(seq) %>%    # sequence from A to B
  map(as_data_frame) %>%                         # convert each element to data frame
  map(~mutate(.,A=min(value), B=max(value))) %>% # add A and B columns
  bind_rows() %>% select(A,B,value)              # combine and reorder columns

答案 2 :(得分:2)

这是一个base R选项,我们通过减去&#39; B&#39;来获得每行times的复制。用&#39; A&#39;列(&#39; i1&#39;),将其创建为列&#39; C&#39;,然后使用&#39; i1&#39;复制原始数据集的行序列。最后,&#39; D&#39;通过获取&#39; A&#39;的相应元素序列来创建列。和&#39; B&#39;使用Map。输出结果为list,因此我们unlist将其设为vector

i1 <- with(d1, B - A + 1) 
d1$C <- i1
d2 <- d1[rep(seq_len(nrow(d1)), i1),]
d2$D <-  unlist(Map(`:`, d1$A, d1$B))
row.names(d2) <- NULL
d2
#   A  B  C  D
#1  2  8  7  2
#2  2  8  7  3
#3  2  8  7  4
#4  2  8  7  5
#5  2  8  7  6
#6  2  8  7  7
#7  2  8  7  8
#8  4  6  3  4
#9  4  6  3  5
#10 4  6  3  6
#11 6  7  2  6
#12 6  7  2  7
#13 8  8  1  8
#14 1 10 10  1
#15 1 10 10  2
#16 1 10 10  3
#17 1 10 10  4
#18 1 10 10  5
#19 1 10 10  6
#20 1 10 10  7
#21 1 10 10  8
#22 1 10 10  9
#23 1 10 10 10

答案 3 :(得分:2)

使用N的简单示例(k = 1的情况)

library(dplyr)

# example data frame
d1 <- data.frame(A=c(2,4,6,8,1),B=c(8,6,7,8,10))

# function to use (must have same column names)
f = function(d) {
  A = rep(d$A, d$diff)
  B = rep(d$B, d$diff)
  C = seq(d$A, d$B)
  data.frame(A, B, C) }


d1 %>%
  mutate(diff = B - A + 1) %>%  # calculate difference
  rowwise() %>%                 # for every row
  do(f(.)) %>%                  # apply the function
  ungroup()                     # forget the grouping

#  # A tibble: 23 x 3
#       A     B     C
# * <dbl> <dbl> <int>
# 1     2     8     2
# 2     2     8     3
# 3     2     8     4
# 4     2     8     5
# 5     2     8     6
# 6     2     8     7
# 7     2     8     8
# 8     4     6     4
# 9     4     6     5
# 10    4     6     6
# # ... with 13 more rows

所有行都有一个k的示例(我使用0.25来演示)

# example data frame
d1 <- data.frame(A=c(2,4,6,8,1),B=c(8,6,7,8,10))

# function to use (must have same column names)
f = function(d, k) {
  A = d$A
  B = d$B
  C = seq(d$A, d$B, k)
  data.frame(A, B, C) }


d1 %>%
  rowwise() %>%       # for every row
  do(f(., 0.25)) %>%   # apply the function using your own k
  ungroup()   

#  # A tibble: 77 x 3
#       A     B     C
# * <dbl> <dbl> <dbl>
# 1     2     8  2.00
# 2     2     8  2.25
# 3     2     8  2.50
# 4     2     8  2.75
# 5     2     8  3.00
# 6     2     8  3.25
# 7     2     8  3.50
# 8     2     8  3.75
# 9     2     8  4.00
# 10    2     8  4.25
# # ... with 67 more rows

每行有不同k的示例

# example data frame
# give manually different k for each row
d1 <- data.frame(A=c(2,4,6,8,1),B=c(8,6,7,8,10))
d1$k = c(0.5, 1, 2, 0.25, 1.5)

d1

#   A  B    k
# 1 2  8 0.50
# 2 4  6 1.00
# 3 6  7 2.00
# 4 8  8 0.25
# 5 1 10 1.50


# function to use (must have same column names)
f = function(d) {
  A = d$A
  B = d$B
  C = seq(d$A, d$B, d$k)
  data.frame(A, B, C) }


d1 %>%
  rowwise() %>%   # for every row
  do(f(.)) %>%    # apply the function using different k for each row
  ungroup() 

#  # A tibble: 25 x 3
#       A     B     C
# * <dbl> <dbl> <dbl>
# 1     2     8   2.0
# 2     2     8   2.5
# 3     2     8   3.0
# 4     2     8   3.5
# 5     2     8   4.0
# 6     2     8   4.5
# 7     2     8   5.0
# 8     2     8   5.5
# 9     2     8   6.0
# 10    2     8   6.5
# # ... with 15 more rows