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

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

问题描述:

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

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序列的新列。

我可以使用下面的代码创建一个数据集。

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 

但它需要很长时间。有没有可能加快这个过程?

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 

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

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

谢谢,索托斯。它在我的情况下工作正常。 – 789372u

你可以使用列表和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 

这里是一个base R选项,我们通过“减去“B”得到的每一行的复制times '列'('i1'),将其创建为列'C',然后使用'i1'复制原始数据集的行序列。最后,'D'列是通过使用Map获得'A'和'B'的对应元素的序列而创建的。输出将是一个list,所以我们unlist它使用N-作出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 

简单的例子(情况下,其中k = 1),你必须对所有行一个K

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 

实施例(我使用的是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 
+0

非常感谢您的帮助。它帮助我很多。这里我有一个小问题,如果** K **是0.02,那么我们该怎么做? – 789372u

+0

那么,K = 0.02将成为你序列中的一步?你希望在这个例子的C列中看到它,如2,2.02,2.04,.....,8?那么这是如何影响N的差异并且等于7呢?你可以给我一个例子吗?我觉得K必须是一个,因为每次创建N行时,没有更多空间来存储具有更多元素的序列。 – AntoniosK

+0

嗨Antoniosk,当我改变我的步骤(** k **)值时,** N **值也会改变。在上面的例子中,如果我们改变** k ** = 0.02,那么** N **就变成301.为了达到这个目的,我们需要在上面的代码中改变setDT(d1)[,C:=( B - A)*(1/k)+ 1]' – 789372u