2017-07-29 58 views
2

我想重複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 

但它需要很長時間。有沒有可能加快這個過程?

回答

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 

注意你可以在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

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

這裏是一個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 
2

簡單的例子(情況下,其中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