我想R中,很容易在Excel中完成執行一個簡單的操作:連續添加值前一個R中
我有一個山坳由5045項叫K.我想創建第二個列L,其中第一個值是L1 = 100 + K [1],第二個是L2 = L1 + K [2],第三個是L3 = L2 + K [3]依此類推。
有沒有一種簡單的方法來做到這一點在R?在Excel中,只需拉下列。
我想R中,很容易在Excel中完成執行一個簡單的操作:連續添加值前一個R中
我有一個山坳由5045項叫K.我想創建第二個列L,其中第一個值是L1 = 100 + K [1],第二個是L2 = L1 + K [2],第三個是L3 = L2 + K [3]依此類推。
有沒有一種簡單的方法來做到這一點在R?在Excel中,只需拉下列。
嘗試像
L <- 100 + cumsum(K)
一種方法是使用cumsum()
和欺騙了一些。例如,給定K
:
K <- 1:10
,並讓事情變得簡單,我加入1
(不100
)到K[1]
,我們要生產:
> 1 + K[1]
[1] 2
> (1 + K[1]) + K[2]
[1] 4
> ((1 + K[1]) + K[2]) + K[3]
[1] 7
....
這是一個累積總和。我們需要用你想添加到第一個元素的常量來作弊,因爲我們只想要影響第一個元素,而不是添加到每個元素。因此,這是錯誤
> L <- cumsum(1 + K)
> L
[1] 2 5 9 14 20 27 35 44 54 65
我們真正想要的是:
> L <- cumsum(c(1, K))[-1]
> L
[1] 2 4 7 11 16 22 29 37 46 56
其中我們串接不斷向矢量K
作爲第一個元素,並應用cumsum()
到這一點,但下降的第一要素的輸出從cumsum()
。
當然,這可以在一個稍微簡單的方式來完成:
> L <- 1 + cumsum(K)
> L
[1] 2 4 7 11 16 22 29 37 46 56
即計算cumusum()
和然後添加的常數(我現在看到的是@ gd047在他們的回答已經暗示了什麼。 )
以下顯示for
基於循環的解決方案。這可能不是你想要的速度,其中向量化函數如cumsum
要快得多。
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]
}
一些計時:
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
這表明使用cumsum
比使用顯式的for循環快幾百倍。當sample_data
的長度增加時,這種效果將更加明顯。
如Paul Hiemstra所示,內建函數cumsum()
很快。 但是,for循環解決方案可以通過使用編譯器包加速。
library(compiler)
fls_compiled <- cmpfun(for_loop_solution)
然後使用相同的數據讓我們運行benchmark
如下
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
所以儘可能使用內建函數。 如果沒有內建,請嘗試編譯程序包。它通常提供更快的代碼。
+1整潔 - 當我開始寫答案的時候,我錯過了,只是因爲當我剛完成時纔開始寫作。 –
+1我很難找到一個矢量化的解決方案,並回到使用'for'循環。我的答案中的時間表明,與使用'cumsum'相比,這非常緩慢。 –