R 以编程方式为一组范围之间的数据创建分组列
我想在R data.table中创建一个分组列,该列允许我根据特定的代码表对数据进行分组,该代码表由代码向量中项目之间的范围确定 我曾经尝试过使用一系列条件进行游程编码,但这似乎非常麻烦,并且无法返回我需要的确切结果R 以编程方式为一组范围之间的数据创建分组列,r,data.table,R,Data.table,我想在R data.table中创建一个分组列,该列允许我根据特定的代码表对数据进行分组,该代码表由代码向量中项目之间的范围确定 我曾经尝试过使用一系列条件进行游程编码,但这似乎非常麻烦,并且无法返回我需要的确切结果 library(data.table) t <- seq.int(from = 0, to = 1, length.out = 10) data <- rnorm(10) dt <- data.table(t, data) code_t <- c(0.
library(data.table)
t <- seq.int(from = 0, to = 1, length.out = 10)
data <- rnorm(10)
dt <- data.table(t, data)
code_t <- c(0.2, 0.3, 0.6, 0.7)
codes <- c("A", "B", "C", "D")
code_dt <- data.table(code_t, codes)
库(data.table)
t我不是data.table
包的专家,但我会按如下方式解决您的问题。首先我装上包裹
#包
库(数据表)
然后我创建了和你一样的向量
#数据
t 4:0.3333333-0.11504042 B
#>5:0.444-1.37218034 B
#>6:0.556 0.02826155 B
#>7:0.66667 1.57980554摄氏度
#>8:0.77778-0.5901697d
#>9:0.88889 1.00988949 D
#>10:1.0000000.42934448 D
由(v0.3.0)创建于2019-09-11这是您想要的吗
dt[, code := code_dt[.SD, on = .(code_t <= t), mult = "last", codes]]
dt
# t data code
# 1: 0.0000000 1.4093115 <NA>
# 2: 0.1111111 -0.5233412 <NA>
# 3: 0.2222222 0.6517409 A
# 4: 0.3333333 0.5204115 B
# 5: 0.4444444 -1.1126457 B
# 6: 0.5555556 0.5156077 B
# 7: 0.6666667 -0.6376642 C
# 8: 0.7777778 0.2816557 D
# 9: 0.8888889 0.1195879 D
# 10: 1.0000000 -1.8018463 D
dt[,code:=code_dt[.SD,on=。(code_t我编写了一个易于扩展和操作的函数。我测试了代码,它在不需要加载任何库的情况下工作
assingGroups <- function(x,ranges,codes){
cnt=1;
for (i in ranges[-length(ranges)]){
mask <- x$t >= ranges[cnt] & x$t<ranges[cnt+1]
x$grouped[mask] <- codes[cnt]
cnt<-cnt+1;
}
### assign the last name to remaining 'NA'
x$grouped[x$grouped=='NA'] <-codes[cnt]
return(x)
}
现在只需运行函数即可获得新的数据帧:
dt<- assingGroups(dt,code_t,codes)
force(dt)
为了完整性起见,data.table
允许滚动联接,它是以下内容的替代:
t数据代码
1: 0.0000000 0.4728356
2: 0.1111111 -0.1761036
3:0.222222-0.5259357 A
4:0.3333333 0.9995843 B
5:0.444-0.3971852 B
6:0.556 1.3734871 B
7:0.66667-1.5221889摄氏度
8:0.778 0.3299245 D
9:0.88889-0.9149123 D
10:1000000-1.1195691 D
很好,cut似乎总是能满足我的需求,但我从来没有立即看到实现。谢谢!我在数据表dt[,code:=cut(t,breaks=c(coded_1,1),labels=code]中使用了您的指导来实现这一点当多个code
位于t
和data
之间的时间间隔内时会发生什么情况。第9行匹配A、B、C和D…@Wimpel我想你误解了这个问题。data
列仅用于示例中的说明目的(我的错)代码分配的间隔由“代码> >代码> <代码>的相邻成员决定。请考虑查看您的答案。OP请求分组<代码> T <代码> -> <代码>数据>代码>。您的答案可能是正确的,但应用于 Dt<代码>的错误列。谢谢。我所写的是一个通用函数TH。at可以应用于数据框中的任何列a。可以重命名数据框中的列以适应不同的问题。例如,colnames(dt)这是一个真实的、可扩展的答案。尽管使用cut
是可能的,但是如果数据很大,滚动连接会更快。@Uwe有趣。我们的答案非常相似。也许你对差异有什么要说的?我本以为@PavoDive是这样的,但当我从agila和rol中对cut方法进行基准测试时ling在我的真实数据上加入了Uwe的方法cut方法的速度快得多。cut方法的另一个优点是,如果我不想在整个数据集上应用标签,它还允许我轻松地输入自定义中断。
code_t <- c(0.2, 0.3, 0.6, 0.7)
codes <- c("A", "B", "C", "D")
dt=data.frame(c(runif(10,0,1)),rep('NA',10),stringsAsFactors =FALSE)
colnames(dt) <- c("t","grouped")
dt
>dt
t grouped
1 0.20846488 NA
2 0.62090310 NA
3 0.43246382 NA
4 0.24366974 NA
5 0.34148940 NA
6 0.01985644 NA
7 0.52140747 NA
8 0.09040793 NA
9 0.47128141 NA
10 0.62571187 NA
dt<- assingGroups(dt,code_t,codes)
force(dt)
> force(dt)
t grouped
1 0.20846488 A
2 0.62090310 C
3 0.43246382 B
4 0.24366974 A
5 0.34148940 B
6 0.01985644 D
7 0.52140747 B
8 0.09040793 D
9 0.47128141 B
10 0.62571187 C
library(data.table)
dt[, codes := code_dt[dt, on = .(code_t = t), roll = TRUE, x.codes]]
dt
t data codes
1: 0.0000000 0.4728356 <NA>
2: 0.1111111 -0.1761036 <NA>
3: 0.2222222 -0.5259357 A
4: 0.3333333 0.9995843 B
5: 0.4444444 -0.3971852 B
6: 0.5555556 1.3734871 B
7: 0.6666667 -1.5221889 C
8: 0.7777778 0.3299245 D
9: 0.8888889 -0.9149123 D
10: 1.0000000 -1.1195691 D