R - 将数值向量拆分为区间
R - Split numeric vector into intervals
我有一个关于向量 "splitting" 的问题,尽管不同的方法可能是可行的。我有一个 data.frame(df) 看起来像这样(简化版):
case time
1 1 5
2 2 3
3 3 4
"time" 变量计算事件发生前的时间单位(天、周等)。我想通过增加行数和 "split" 来扩展数据集 "time" 到长度为 1 的间隔,从 2 开始。结果可能看起来像这样:
case time begin end
1 1 5 2 3
2 1 5 3 4
3 1 5 4 5
4 2 3 2 3
5 3 4 2 3
6 3 4 3 4
很明显,我的数据集比这个例子要大一些。实现这个结果的可行方法是什么?
我有一个想法从
开始
df.exp <- df[rep(row.names(df), df$time - 2), 1:2]
为了扩大每个案例的行数,根据时间间隔的数量。基于此,可能会以以下方式添加 "begin" 和 "end" 列:
df.exp$begin <- 2:(df.exp$time-1)
但是,我并没有成功创建相应的列,因为该命令仅使用第一行来计算 (df.exp$time-1) 而不会自动区分 "case".
任何想法将不胜感激!
你可以试试
df2 <- df1[rep(1:nrow(df1), df1$time-2),]
row.names(df2) <- NULL
m1 <- do.call(rbind,
Map(function(x,y) {
v1 <- seq(x,y)
cbind(v1[-length(v1)],v1[-1L])},
2, df1$time))
df2[c('begin', 'end')] <- m1
df2
# case time begin end
#1 1 5 2 3
#2 1 5 3 4
#3 1 5 4 5
#4 2 3 2 3
#5 3 4 2 3
#6 3 4 3 4
或者 data.table
的选项
library(data.table)
setDT(df1)[,{tmp <- seq(2, time)
list(time= time,
begin= tmp[-length(tmp)],
end=tmp[-1])} , by = case]
# case time begin end
#1: 1 5 2 3
#2: 1 5 3 4
#3: 1 5 4 5
#4: 2 3 2 3
#5: 3 4 2 3
#6: 3 4 3 4
library(data.table)
DT <- as.data.table(df)
DT[, rep(time, time-2), case][, begin := 2:(.N+1), case][, end := begin +1][]
# case V1 begin end
#1: 1 5 2 3
#2: 1 5 3 4
#3: 1 5 4 5
#4: 2 3 2 3
#5: 3 4 2 3
#6: 3 4 3 4
我有一个关于向量 "splitting" 的问题,尽管不同的方法可能是可行的。我有一个 data.frame(df) 看起来像这样(简化版):
case time
1 1 5
2 2 3
3 3 4
"time" 变量计算事件发生前的时间单位(天、周等)。我想通过增加行数和 "split" 来扩展数据集 "time" 到长度为 1 的间隔,从 2 开始。结果可能看起来像这样:
case time begin end
1 1 5 2 3
2 1 5 3 4
3 1 5 4 5
4 2 3 2 3
5 3 4 2 3
6 3 4 3 4
很明显,我的数据集比这个例子要大一些。实现这个结果的可行方法是什么?
我有一个想法从
开始df.exp <- df[rep(row.names(df), df$time - 2), 1:2]
为了扩大每个案例的行数,根据时间间隔的数量。基于此,可能会以以下方式添加 "begin" 和 "end" 列:
df.exp$begin <- 2:(df.exp$time-1)
但是,我并没有成功创建相应的列,因为该命令仅使用第一行来计算 (df.exp$time-1) 而不会自动区分 "case".
任何想法将不胜感激!
你可以试试
df2 <- df1[rep(1:nrow(df1), df1$time-2),]
row.names(df2) <- NULL
m1 <- do.call(rbind,
Map(function(x,y) {
v1 <- seq(x,y)
cbind(v1[-length(v1)],v1[-1L])},
2, df1$time))
df2[c('begin', 'end')] <- m1
df2
# case time begin end
#1 1 5 2 3
#2 1 5 3 4
#3 1 5 4 5
#4 2 3 2 3
#5 3 4 2 3
#6 3 4 3 4
或者 data.table
library(data.table)
setDT(df1)[,{tmp <- seq(2, time)
list(time= time,
begin= tmp[-length(tmp)],
end=tmp[-1])} , by = case]
# case time begin end
#1: 1 5 2 3
#2: 1 5 3 4
#3: 1 5 4 5
#4: 2 3 2 3
#5: 3 4 2 3
#6: 3 4 3 4
library(data.table)
DT <- as.data.table(df)
DT[, rep(time, time-2), case][, begin := 2:(.N+1), case][, end := begin +1][]
# case V1 begin end
#1: 1 5 2 3
#2: 1 5 3 4
#3: 1 5 4 5
#4: 2 3 2 3
#5: 3 4 2 3
#6: 3 4 3 4