[英]Splitting the sequence of values of a time-varying variable, conditionally on id
在分析的數據管理步驟中,我遇到了以下問題。
實際上,每個id
最多記錄5次,並且我有一個隨時間變化的變量tv = 1, 2, 3, 4
。 假設我的數據是:
dat <- read.table(text = "
id tv
1 2
1 2
1 1
1 4
2 4
2 1
2 4
3 1
3 2
3 3
3 3
3 2",
header=TRUE)
我需要做的是從tv
創建兩個新的變量集,以獲得:
id tv tv1 tv2 tv3 tv4 tv5 dur1 dur2 dur3 dur4 dur5
1 2 2 1 4 0 0 2 1 1 0 0
1 2 2 1 4 0 0 2 1 1 0 0
1 1 2 1 4 0 0 2 1 1 0 0
1 4 2 1 4 0 0 2 1 1 0 0
2 4 4 1 4 0 0 1 1 1 0 0
2 1 4 1 4 0 0 1 1 1 0 0
2 4 4 1 4 0 0 1 1 1 0 0
3 1 1 2 3 2 0 1 1 2 1 0
3 2 1 2 3 2 0 1 1 2 1 0
3 3 1 2 3 2 0 1 1 2 1 0
3 3 1 2 3 2 0 1 1 2 1 0
3 2 1 2 3 2 0 1 1 2 1 0
對於每個id
,在tv1
- tv5
我們有不同的(不重復)的記錄的有序序列tv
,而在dur1
- dur5
我們的次數相應的不同的記錄存在於原始數據集dat
。
我真的不知道該如何進行。任何幫助將不勝感激。
應該這樣做:
require(plyr)
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L,
3L, 3L), tv = c(2L, 2L, 1L, 4L, 4L, 1L, 4L, 1L, 2L, 3L, 3L, 2L
)), .Names = c("id", "tv"), class = "data.frame", row.names = c(NA,
-12L))
out <- ddply(dat, .(id), function(x) {
this.rle <- rle(x$tv)
val <- this.rle$values
val <- c(val, rep(0, 5-length(val)))
val <- matrix(rep(val,nrow(x)), byrow=T, nrow=nrow(x))
val <- as.data.frame(val)
names(val) <- paste("tv", 1:5, sep="")
len <- this.rle$lengths
len <- c(len, rep(0, 5-length(len)))
len <- matrix(rep(len,nrow(x)), byrow=T, nrow=nrow(x))
len <- as.data.frame(len)
names(len) <- paste("dur", 1:5, sep="")
cbind(data.frame(tv=x$tv), val, len)
})
> out
id tv tv1 tv2 tv3 tv4 tv5 dur1 dur2 dur3 dur4 dur5
1 1 2 2 1 4 0 0 2 1 1 0 0
2 1 2 2 1 4 0 0 2 1 1 0 0
3 1 1 2 1 4 0 0 2 1 1 0 0
4 1 4 2 1 4 0 0 2 1 1 0 0
5 2 4 4 1 4 0 0 1 1 1 0 0
6 2 1 4 1 4 0 0 1 1 1 0 0
7 2 4 4 1 4 0 0 1 1 1 0 0
8 3 1 1 2 3 2 0 1 1 2 1 0
9 3 2 1 2 3 2 0 1 1 2 1 0
10 3 3 1 2 3 2 0 1 1 2 1 0
11 3 3 1 2 3 2 0 1 1 2 1 0
12 3 2 1 2 3 2 0 1 1 2 1 0
這完全是基於R的解決方案。它與@Arun的答案非常相似,但可能比使用“ plyr”要快:
out <- cbind(dat, do.call(
rbind,
lapply(split(dat$tv, dat$id), function(x) {
OUT <- matrix(0, ncol = 10, nrow = 1)
T1 <- rle(x)
OUT[1, seq_along(T1$values)] <- T1$values
OUT[1, 6:(5+length(T1$lengths))] <- T1$lengths
colnames(OUT) <- paste(rep(c("tv", "dur"),
each = 5), 1:5, sep ="")
OUT[rep(1, length(x)), ]
})))
out
# id tv tv1 tv2 tv3 tv4 tv5 dur1 dur2 dur3 dur4 dur5
# 1 1 2 2 1 4 0 0 2 1 1 0 0
# 2 1 2 2 1 4 0 0 2 1 1 0 0
# 3 1 1 2 1 4 0 0 2 1 1 0 0
# 4 1 4 2 1 4 0 0 2 1 1 0 0
# 5 2 4 4 1 4 0 0 1 1 1 0 0
# 6 2 1 4 1 4 0 0 1 1 1 0 0
# 7 2 4 4 1 4 0 0 1 1 1 0 0
# 8 3 1 1 2 3 2 0 1 1 2 1 0
# 9 3 2 1 2 3 2 0 1 1 2 1 0
# 10 3 3 1 2 3 2 0 1 1 2 1 0
# 11 3 3 1 2 3 2 0 1 1 2 1 0
# 12 3 2 1 2 3 2 0 1 1 2 1 0
這是正在發生的事情的摘要:
split(dat$tv, dat$id)
為每個“ id”在“ tv”中創建值列表。
我們應用匿名函數,其中:
rle()
的輸出,因為我們需要“值”和“長度” do.call(rbind...
將所有矩陣放在一起,按行綁定它們。
cbind(dat...
將原始data.frame
綁定到步驟1至3的結果。
再次,從概念上講,這與Arun的答案非常相似-使用rle()
可能正是您所缺少的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.