2012-10-24 45 views
5

Tôi muốn thực hiện thao tác đơn giản trong R dễ dàng thực hiện trong excel:Thêm các giá trị vào hàng trước vào R

Tôi có một danh mục gồm 5045 mục K. Tôi muốn tạo ra một col thứ hai L, nơi giá trị đầu tiên là L1 = 100 + K [1] thứ hai là L2 = L1 + K [2], thứ ba là L3 = L2 + K [3] và như vậy.

Có cách nào đơn giản để thực hiện việc này trong R không? trong Excel chỉ cần kéo xuống col.

Trả lời

7

Hãy thử một cái gì đó giống như

L <- 100 + cumsum(K) 
+0

+1 Gọn gàng - Tôi đã bỏ lỡ điều đó khi tôi bắt đầu viết Câu trả lời của mình, chỉ để nó bình minh cho tôi khi tôi kết thúc. –

+0

+1 Tôi đã gặp khó khăn trong việc tìm kiếm một giải pháp được vector hóa và quay trở lại sử dụng vòng lặp 'for'. Thời gian trong câu trả lời của tôi cho thấy rằng điều này là khủng khiếp chậm so với sử dụng 'cumsum'. –

4

Một cách tiếp cận là sử dụng cumsum() và lừa dối một chút. Ví dụ, cho K:

K <- 1:10 

và để giữ cho mọi thứ đơn giản tôi thêm 1 (không 100) để K[1], chúng tôi muốn sản xuất:

> 1 + K[1] 
[1] 2 
> (1 + K[1]) + K[2] 
[1] 4 
> ((1 + K[1]) + K[2]) + K[3] 
[1] 7 
.... 

Đây là một khoản tiền tích lũy. Chúng tôi cần phải ăn gian một chút với hằng số bạn muốn thêm vào phần tử đầu tiên vì chúng tôi chỉ muốn điều đó ảnh hưởng đến yếu tố đầu tiên đó, không được thêm vào từng phần tử. Do đó đây là sai

> L <- cumsum(1 + K) 
> L 
[1] 2 5 9 14 20 27 35 44 54 65 

gì chúng tôi thực sự muốn là:

> L <- cumsum(c(1, K))[-1] 
> L 
[1] 2 4 7 11 16 22 29 37 46 56 

Trong đó chúng tôi tiếp nhau hằng số vào vector K là yếu tố đầu tiên và áp dụng cumsum() đó, nhưng thả các phần tử đầu tiên của đầu ra từ cumsum().

lon Điều này tất nhiên được thực hiện trong một thời trang tương đối đơn giản:

> L <- 1 + cumsum(K) 
> L 
[1] 2 4 7 11 16 22 29 37 46 56 

tức là tính toán cumusum()sau đó thêm vào hằng số (mà bây giờ tôi thấy là những gì @ gd047 đã đề xuất trong trả lời của họ.)

0

Sau đây cho thấy giải pháp dựa trên vòng lặp for. Điều này có lẽ không phải là những gì bạn muốn về tốc độ, nơi mà các chức năng vectorized như cumsum nhanh hơn nhiều.

a = 1:10 
b = vector(mode = "numeric", length = length(a)) 
b[1] = 1 + a[1] 

for(idx in 2:length(a)) { 
    b[idx] = a[idx] + b[idx - 1] 
} 

Một số timings:

require(rbenchmark) 

for_loop_solution = function(a) { 
    b = vector(mode = "numeric", length = length(a)) 
    b[1] = 1 + a[1] 

    for(idx in 2:length(a)) { 
     b[idx] = a[idx] + b[idx - 1] 
    } 
    return(invisible(b)) 
} 

cumsum_solution = function(a) { 
    return(1 + cumsum(a)) 
} 

sample_data = 1:10e3 
benchmark(for_loop_solution(sample_data), 
      cumsum_solution(sample_data), 
      replications = 100) 
          test replications elapsed relative user.self 
2 cumsum_solution(sample_data)   100 0.013 1.000  0.011 
1 for_loop_solution(sample_data)   100 3.647 280.538  3.415 
    sys.self user.child sys.child 
2 0.002   0   0 
1 0.006   0   0 

trong đó cho thấy rằng việc sử dụng cumsum là nhanh hơn so với việc sử dụng một rõ ràng cho vòng một vài trăm lần. Hiệu ứng này thậm chí còn rõ rệt hơn khi độ dài của sample_data tăng lên.

0

Như được hiển thị bởi Paul Hiemstra hàm dựng sẵn cumsum() là nhanh. Nhưng giải pháp vòng lặp for có thể được tăng tốc bằng cách sử dụng gói trình biên dịch.

library(compiler) 
fls_compiled <- cmpfun(for_loop_solution) 

Sau đó, sử dụng cùng một dữ liệu chúng ta hãy chạy benchmark như sau

benchmark(for_loop_solution(sample_data), 
      cumsum_solution(sample_data), 
      fls_compiled(sample_data), 
      replications = 100) 
          test replications elapsed relative user.self 
2 cumsum_solution(sample_data)   100 0.013 1.000  0.013 
3  fls_compiled(sample_data)   100 0.726 55.846  0.717 
1 for_loop_solution(sample_data)   100 4.417 339.769  3.723 
    sys.self user.child sys.child 
2 0.000   0   0 
3 0.006   0   0 
1 0.031   0   0 

Vì vậy, sử dụng các chức năng được xây dựng trong bất cứ nơi nào có thể. Và nếu không có nội trang dựng sẵn, hãy thử gói trình biên dịch. Nó thường cung cấp mã nhanh hơn.

Các vấn đề liên quan