我有这样一个数据:
d <- data.frame(
ab = c(3, 4, 2, 6),
dur_1 = c(32, 1, 3, 4),
dur_2 = c(27, 9, 26, 5),
dur_3 = c(25, 8, 21, 48),
dur_5 = c(0, 4, 0, 42),
dur_6 = c(0, 0, 0, 0),
dur_7 = c(0, 0, 0, 0),
cd = c(45, 67, 34, 78)
)
我想做的是创建一个新列pre_dur
。pre_dur
是以dur_
开始的变量的前几行的最后一个非负值。因此,要获得pre_dur
,请扫描前一行中的dur_
变量,找到数字开始变为零的位置。最后一个非负数就是我想要的值。
我的预期输出应该是这样的:
d1<-data.frame(ab=c(3,4,2,6),
dur_1=c(32,1,3,4),
dur_2=c(27,9,26,5),
dur_3=c(25,8,21,48),
dur_5=c(0,4,0,42),
dur_6=c(0,0,0,0),
dur_7=c(0,0,0,0),
cd=c(45,67,34,78),
pre_dur=c(NA,25,4,21))
实际上下面的代码工作:
d1 <- d %>%
mutate(pre_dur = case_when(lag(dur_7) > 0 ~ lag(dur_7),
lag(dur_6) > 0 ~ lag(dur_6),
lag(dur_5) > 0 ~ lag(dur_5),
lag(dur_3) > 0 ~ lag(dur_3),
lag(dur_2) > 0 ~ lag(dur_2),
lag(dur_1) > 0 ~ lag(dur_1),
TRUE ~ NA_real_))
但在我的实际数据中,dur_
后面的自然数是可以改变的。所以我需要一个通用代码。如何做到这一点?
3条答案
按热度按时间enyaitl31#
这个解决方案怎么样?
这假设一旦一个值下降到0,那么它就不会增加。如果不是这种情况,那么
ifelse
语句需要捕获它。swvgeqrz2#
首先,找到每个组的值,然后将其滞后一次。我们可以使用
rowwise()
来实现,但是将其转换为长格式并再转换回来可能更快,可读性更强。即sxissh063#
在base中使用
max.col
与last
的方法。