从 data.table 中仅删除初始 NA 值
Remove only initial NA values from data.table
在下面的 data.table 中,我想删除所有的 NA 值,直到在列 y
中遇到至少两个连续的数值。根据此条件,应从下面的 table 中删除从 1 到 9 的所有行。
由于我是在清理大量的组,如果解决方案考虑到性能部分就更好了。
temp_dt = structure(list(group = c("B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "B"), x = c(940, 960,
980, 1000, 1040, 1060, 1080, 1100, 1100, 1120, 1140, 1160, 1180,
1190, 1200, 1200, 1220, 1240, 1260, 1280, 1300, 1300, 1320, 1340,
1360, 1380, 1400, 1400, 1410, 1420), y = c(NA, NA, NA, NA, NA,
NA, NA, 0.525, NA, 2.425, 2.425, NA, NA, NA, 2.425, NA, 2.425,
1.975, 2.45, 2.45, 1.2, NA, NA, 2.275, 2.375, 2.75, 2.675, NA,
2.75, 3.05)), row.names = c(NA, -30L), class = c("data.table",
"data.frame"))
group x y
1: B 940 NA
2: B 960 NA
3: B 980 NA
4: B 1000 NA
5: B 1040 NA
6: B 1060 NA
7: B 1080 NA
8: B 1100 0.525
9: B 1100 NA
10: B 1120 2.425
11: B 1140 2.425
12: B 1160 NA
13: B 1180 NA
14: B 1190 NA
15: B 1200 2.425
16: B 1200 NA
17: B 1220 2.425
18: B 1240 1.975
19: B 1260 2.450
20: B 1280 2.450
21: B 1300 1.200
22: B 1300 NA
23: B 1320 NA
24: B 1340 2.275
25: B 1360 2.375
26: B 1380 2.750
27: B 1400 2.675
28: B 1400 NA
29: B 1410 2.750
30: B 1420 3.050
group x y
我认为解决方案从创建一组 NA 值开始,但不知道如何进一步进行 -
temp_dt[, na_grp := rleid(is.na(y)), by = group]
下面的代码部分解决了我的问题,唯一没有解决的是两个连续的值 -
temp_dt[!is.na(y) & !na_grp %in% c(1L)]
您可以使用 shift
来测试两个连续的值,并使用 cumsum
在满足初始触发条件后保持选择:
temp_dt[,.SD[cumsum(!is.na(y)&!is.na(shift(y,-1)))>0],by=group]
group x y
1: B 1120 2.425
2: B 1140 2.425
3: B 1160 NA
4: B 1180 NA
5: B 1190 NA
6: B 1200 2.425
7: B 1200 NA
8: B 1220 2.425
9: B 1240 1.975
10: B 1260 2.450
11: B 1280 2.450
12: B 1300 1.200
13: B 1300 NA
14: B 1320 NA
15: B 1340 2.275
16: B 1360 2.375
17: B 1380 2.750
18: B 1400 2.675
19: B 1400 NA
20: B 1410 2.750
21: B 1420 3.050
在下面的 data.table 中,我想删除所有的 NA 值,直到在列 y
中遇到至少两个连续的数值。根据此条件,应从下面的 table 中删除从 1 到 9 的所有行。
由于我是在清理大量的组,如果解决方案考虑到性能部分就更好了。
temp_dt = structure(list(group = c("B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B", "B", "B"), x = c(940, 960,
980, 1000, 1040, 1060, 1080, 1100, 1100, 1120, 1140, 1160, 1180,
1190, 1200, 1200, 1220, 1240, 1260, 1280, 1300, 1300, 1320, 1340,
1360, 1380, 1400, 1400, 1410, 1420), y = c(NA, NA, NA, NA, NA,
NA, NA, 0.525, NA, 2.425, 2.425, NA, NA, NA, 2.425, NA, 2.425,
1.975, 2.45, 2.45, 1.2, NA, NA, 2.275, 2.375, 2.75, 2.675, NA,
2.75, 3.05)), row.names = c(NA, -30L), class = c("data.table",
"data.frame"))
group x y
1: B 940 NA
2: B 960 NA
3: B 980 NA
4: B 1000 NA
5: B 1040 NA
6: B 1060 NA
7: B 1080 NA
8: B 1100 0.525
9: B 1100 NA
10: B 1120 2.425
11: B 1140 2.425
12: B 1160 NA
13: B 1180 NA
14: B 1190 NA
15: B 1200 2.425
16: B 1200 NA
17: B 1220 2.425
18: B 1240 1.975
19: B 1260 2.450
20: B 1280 2.450
21: B 1300 1.200
22: B 1300 NA
23: B 1320 NA
24: B 1340 2.275
25: B 1360 2.375
26: B 1380 2.750
27: B 1400 2.675
28: B 1400 NA
29: B 1410 2.750
30: B 1420 3.050
group x y
我认为解决方案从创建一组 NA 值开始,但不知道如何进一步进行 -
temp_dt[, na_grp := rleid(is.na(y)), by = group]
下面的代码部分解决了我的问题,唯一没有解决的是两个连续的值 -
temp_dt[!is.na(y) & !na_grp %in% c(1L)]
您可以使用 shift
来测试两个连续的值,并使用 cumsum
在满足初始触发条件后保持选择:
temp_dt[,.SD[cumsum(!is.na(y)&!is.na(shift(y,-1)))>0],by=group]
group x y
1: B 1120 2.425
2: B 1140 2.425
3: B 1160 NA
4: B 1180 NA
5: B 1190 NA
6: B 1200 2.425
7: B 1200 NA
8: B 1220 2.425
9: B 1240 1.975
10: B 1260 2.450
11: B 1280 2.450
12: B 1300 1.200
13: B 1300 NA
14: B 1320 NA
15: B 1340 2.275
16: B 1360 2.375
17: B 1380 2.750
18: B 1400 2.675
19: B 1400 NA
20: B 1410 2.750
21: B 1420 3.050