R 用下一行中的值对数据表中的值进行矢量化条件替换
我需要对一大组数据执行以下操作。以下是问题的简单版本:R 用下一行中的值对数据表中的值进行矢量化条件替换,r,data.table,vectorization,R,Data.table,Vectorization,我需要对一大组数据执行以下操作。以下是问题的简单版本: dt = data.table(start = c(1, 10, 20, 30, 40, 50), end = c(5, 15, 100, 35, 45, 55)) final = 75 print(dt) for (i in 1:dim(dt)[1]) { if (dt[i, end] > final) dt[i, end := dt[i+1, start]] } print(dt) 输出: # initial
dt = data.table(start = c(1, 10, 20, 30, 40, 50), end = c(5, 15, 100, 35, 45, 55))
final = 75
print(dt)
for (i in 1:dim(dt)[1]) {
if (dt[i, end] > final)
dt[i, end := dt[i+1, start]]
}
print(dt)
输出:
# initial
start end
1: 1 5
2: 10 15
3: 20 100
4: 30 35
5: 40 45
6: 50 55
# final
start end
1: 1 5
2: 10 15
3: 20 30
4: 30 35
5: 40 45
6: 50 55
基本上,每当end
列中的值大于final
变量时,我希望它替换为下一个start
值(从下一行开始)
我想以某种方式为循环对进行矢量化,因为正如我所提到的,我是在一大组数据上进行这项工作的(同样,我宁愿将它保存在data.table
中,但如果我必须使用dplyr
,也可以)。谢谢。您可以使用:
dt$end<- ifelse(dt$end>final,c(dt$start[-1],max(dt$start)),dt$end)
start end
1: 1 5
2: 10 15
3: 20 30
4: 30 35
5: 40 45
6: 50 55
其中给出(将最后一个值更改为80):
解释c(开始[-1],最大(开始))
:
这(几乎)与shift
:取列start并删除第一个元素,这样新的第一个元素实际上是前一个第二个元素,依此类推,这样就在向量中创建了一个移位。如果删除了一个元素,则需要添加另一个:max(start)
您可以使用以下选项:
dt$end<- ifelse(dt$end>final,c(dt$start[-1],max(dt$start)),dt$end)
start end
1: 1 5
2: 10 15
3: 20 30
4: 30 35
5: 40 45
6: 50 55
其中给出(将最后一个值更改为80):
解释c(开始[-1],最大(开始))
:
这(几乎)与shift
:取列start并删除第一个元素,这样新的第一个元素实际上是前一个第二个元素,依此类推,这样就在向量中创建了一个移位。如果删除了一个元素,则需要添加另一个:max(start)
作为参考,data.table模拟为dt[,end:=ifelse(end>final,shift(start,type=“lead”),end)]
@Frank:shift所需的包装是什么?我尝试使用magic,但随后出现错误“unused argument(type=“lead”)”。data.table包的最新CRAN版本添加了该函数。如果您有另一个包也有一个shift
函数(…因为它是一个常见的名称),那么data.table::shift
可能会起作用。谢谢,@etienne。这同样有效:DT[,end:=ifelse(end>final,c(start[-1],max(start)),end)]
。有人能解释一下它的作用吗?我理解ifelse()函数,但是c(start[-1],max(start)),end)做什么?我还要看一下班次,谢谢@Frank。@Anarcho Chossid etienne为答案添加了一个解释。作为参考,data.table类似物是dt[,end:=ifelse(end>final,shift(start,type=“lead”),end)]
@Frank:班次需要什么套餐?我尝试使用magic,但随后出现错误“unused argument(type=“lead”)”。data.table包的最新CRAN版本添加了该函数。如果您有另一个包也有一个shift
函数(…因为它是一个常见的名称),那么data.table::shift
可能会起作用。谢谢,@etienne。这同样有效:DT[,end:=ifelse(end>final,c(start[-1],max(start)),end)]
。有人能解释一下它的作用吗?我理解ifelse()函数,但是c(start[-1],max(start)),end)做什么?我还将看一看转换
,谢谢@Frank.@Anarcho Chossid etienne为答案添加了一个解释。
dt = data.table(start = c(1, 10, 20, 30, 40, 50), end = c(5, 15, 100, 35, 45, 80))
final = 75
dt[, end := ifelse(end > final, shift(start, type="lead",fill=max(start)), end)]
dt
start end
1: 1 5
2: 10 15
3: 20 30
4: 30 35
5: 40 45
6: 50 50
dt$start
[1] 1 10 20 30 40 50
c(dt$start[-1],max(dt$start)) : you take all the values of start except the first + the max
[1] 10 20 30 40 50 50