2016-07-26 119 views
1

I have read附加到R中的向量是不好的做法。在那種情況下,當我想創建一個矢量時,我應該怎麼做,但是我不知道它的長度?如何在R不知道時間的情況下在R中創建矢量?

我正在查看一個數據框,其中包含有關人們何時靠近特定位置的條目。每個條目都包含關於該人的信息以及附近的時間,但是對於單個人可能有許多條目。

# loc id  time 
# 1: z A  00:00 
# 2: z A  00:01 
# 3: z B  00:02 
# 4: z A  00:02 
# 5: z C  00:05 
# 6: z C  00:07 
# 7: z A  00:08 
# 8: z A  00:09 
# 9: z C  00:09 
#10: z C  00:10 

我想創建一個新的數據幀,其中每個條目是「拜訪」的人,從一個人是在時間上接近整理的任何條目。

# loc id starttime endtime 
# 1: z A  00:00 00:02 
# 2: z C  00:05 00:07 
# 3: z A  00:08 00:09 
# 4: z C  00:09 00:10 

它們可以是一個人在第一數據幀可被整理成在新的數據幀3「訪問」 50個條目。事先我不知道有多少「訪問」。那麼我應該如何去創建這個數據框呢?

我知道rbind,但在這種情況下,我會逐一綁定每一行。這是一個好主意嗎?

另一種選擇是通過第一個數據幀兩次,一次找出第二個數據幀的大小,然後再填充它,但這看起來效率更低。

+0

你只要做,然後追加到它。這就是動態語言如何做到的。這對於那些需要複製的大列表正在擴大的問題更重要。更多的小向量和值R已經在你背後佔據了主導地位。 –

+1

這聽起來有點像你只是想融化和過濾......沒有一個特定的數據例子,但它很難知道。 –

+1

我建議你第2章「成長對象」,它正是你要求的:) http://www.burns-stat.com/pages/Tutor/R_inferno。pdf他提出的解決方案是由@Roland提出的解決方案,但他也分析了系統時間用於完成某些任務的其他方法(在塊中與在rbind與下標之間增長)。 You cn – Eugen

回答

4

我不相信你需要這個(可能有更好的解決方案來描述你的實際問題),但我會在第一段回答這個問題。如果您不知道結果向量需要多大,則將其初始化爲合理的大小,並根據需要將其大小分塊。這限制了向量需要增長的時間。

set.seed(42) 
vec <- numeric(100) #initialize a chunk 
i <- 0 

repeat { 
    test <- rnorm(1) 
    if (test > 3) break 
    i <- i + 1 
    #grow in chunks: 
    if (length(vec) < i) vec <- c(vec, numeric(100)) 
    vec[i] <- test 
} 

#shorten to final length 
vec <- vec[seq_len(i)] 

你在實際生活中實際上做了這樣的事情。如果你購買一個新的書架,你可以買到足夠大的書架,以備將來購買書籍。當它滿了,你買下一個(或更大的)。

+0

我從來沒有見過「重複」 - 非常優雅! – dayne

1

這並沒有明確地回答你的問題,但是展示瞭如何使用cut創建你想要的數據來創建「訪問」,然後計算唯一的訪問次數。

library(data.table) 
set.seed(1234) 
dat <- data.table(visit_time = sample(20, 100, replace = TRUE), 
        id = sample(LETTERS[1:5], 100, replace = TRUE)) 
dat[ , visit := cut(visit_time, breaks = seq(0, 20, 5))] 
dat[ , list(nvisits = length(unique(visit))), by = id] 
# id nvisits 
# 1: A  4 
# 2: C  4 
# 3: B  4 
# 4: D  4 
# 5: E  4 

運行下面的節目,他們同樣時間跨度/就診中有多少時間是在該位置:

dat[ , .N, by = list(id, visit)] 
#  id visit N 
# 1: A (0,5] 6 
# 2: C (10,15] 5 
# 3: B (10,15] 6 
# 4: A (15,20] 3 
# 5: A (10,15] 5 
# 6: D (10,15] 6 
# 7: E (5,10] 7 
# 8: B (5,10] 6 
# 9: E (15,20] 4 
# 10: D (0,5] 6 
# 11: D (5,10] 4 
# 12: E (0,5] 9 
# 13: C (0,5] 4 
# 14: B (15,20] 1 
# 15: C (15,20] 9 
# 16: B (0,5] 6 
# 17: A (5,10] 2 
# 18: C (5,10] 5 
# 19: D (15,20] 2 
# 20: E (10,15] 4 

編輯顯示切換功能將如何隨時間的工作:

我從this excellent answerrandTime功能。

randTime <- function(N, st, et) { 
    st <- as.POSIXct(st) 
    et <- as.POSIXct(et) 
    dt <- as.numeric(difftime(et,st,unit="sec")) 
    ev <- sort(runif(N, 0, dt)) 
    rt <- st + ev 
    rt 
} 

set.seed(1234) 
st <- as.POSIXct("2012/01/01 12:00") 
et <- as.POSIXct("2012/01/01 18:00") 
dat2 <- data.table(visit_time = randTime(100, st, et), 
        id = sample(LETTERS[1:5], 100, replace = TRUE)) 
dat2[ , visit := as.character(cut(visit_time, breaks = seq(st, et, "15 min")))] 
dat2[ , length(unique(visit)), by = id] 
# id V1 
# 1: A 11 
# 2: C 13 
# 3: B 14 
# 4: D 14 
# 5: E 14 
+0

將削減POSIXt或POSIXct訪問時間的工作嗎? – oregano

+0

是的。我可以編輯答案給你看,但@羅蘭真的回答了你問的問題。 – dayne

+0

即你是否真的接受他的答案,不管你是否使用我提供的解決方案。 – dayne