#r #datatable
Вопрос:
У меня есть следующая функция, которая принимает data.table t
и переменную target
в качестве аргументов:
checkDT <- function(t, target){
columns <- c('A', 'B', 'C')
for (i in columns) {
if(suppressWarnings(is.infinite(min(t[get(i) >= target, get(i)])))){
t <- t
}else{
suppressWarnings(t[get(i) > min(t[get(i) >= target, get(i)]), (i) := NA])
}
}
t[]
}
Вот входные данные.таблица t
:
> dput(t[150:250])
structure(list(Week = structure(c(19959, 19966, 19973, 19980,
19987, 19994, 20001, 20008, 20015, 20022, 20029, 20036, 20043,
20050, 20057, 20064, 20071, 20078, 20085, 20092, 20099, 20106,
20113, 20120, 20127, 20134, 20141, 20148, 20155, 20162, 20169,
20176, 20183, 20190, 20197, 20204, 20211, 20218, 20225, 20232,
20239, 20246, 20253, 20260, 20267, 20274, 20281, 20288, 20295,
20302, 20309, 20316, 20323, 20330, 20337, 20344, 20351, 20358,
20365, 20372, 20379, 20386, 20393, 20400, 20407, 20414, 20421,
20428, 20435, 20442, 20449, 20456, 20463, 20470, 20477, 20484,
20491, 20498, 20505, 20512, 20519, 20526, 20533, 20540, 20547,
20554, 20561, 20568, 20575, 20582, 20589, 20596, 20603, 20610,
20617, 20624, 20631, 20638, 20645, 20652, 20659), class = "Date"),
A = c(180L, 181L, 182L, 183L, 183L, 184L, 185L, 186L, 187L,
187L, 188L, 189L, 190L, 190L, 191L, 192L, 193L, 194L, 194L,
195L, 196L, 196L, 197L, 198L, 198L, 199L, 200L, 201L, 201L,
202L, 202L, 203L, 204L, 204L, 205L, 206L, 206L, 207L, 207L,
208L, 209L, 209L, 210L, 210L, 211L, 212L, 212L, 213L, 213L,
214L, 214L, 215L, 215L, 216L, 216L, 217L, 217L, 218L, 218L,
219L, 219L, 220L, 220L, 221L, 221L, 222L, 222L, 223L, 223L,
224L, 224L, 225L, 225L, 226L, 226L, 226L, 227L, 227L, 228L,
228L, 228L, 229L, 229L, 230L, 230L, 230L, 231L, 231L, 232L,
232L, 232L, 233L, 233L, 233L, 234L, 234L, 235L, 235L, 235L,
236L, 236L), B = c(163L, 164L, 165L, 166L, 166L, 167L, 168L,
169L, 170L, 171L, 171L, 172L, 173L, 174L, 175L, 175L, 176L,
177L, 178L, 178L, 179L, 180L, 181L, 181L, 182L, 183L, 183L,
184L, 185L, 185L, 186L, 187L, 187L, 188L, 189L, 189L, 190L,
191L, 191L, 192L, 193L, 193L, 194L, 194L, 195L, 196L, 196L,
197L, 197L, 198L, 198L, 199L, 200L, 200L, 201L, 201L, 202L,
202L, 203L, 203L, 204L, 204L, 205L, 205L, 206L, 206L, 207L,
207L, 208L, 208L, 209L, 209L, 210L, 210L, 211L, 211L, 212L,
212L, 213L, 213L, 213L, 214L, 214L, 215L, 215L, 216L, 216L,
216L, 217L, 217L, 218L, 218L, 218L, 219L, 219L, 219L, 220L,
220L, 221L, 221L, 221L), C = c(146L, 147L, 148L, 149L, 150L,
151L, 151L, 152L, 153L, 154L, 155L, 155L, 156L, 157L, 158L,
159L, 159L, 160L, 161L, 162L, 162L, 163L, 164L, 165L, 165L,
166L, 167L, 168L, 168L, 169L, 170L, 170L, 171L, 172L, 172L,
173L, 174L, 174L, 175L, 176L, 176L, 177L, 178L, 178L, 179L,
179L, 180L, 181L, 181L, 182L, 182L, 183L, 184L, 184L, 185L,
185L, 186L, 186L, 187L, 187L, 188L, 189L, 189L, 190L, 190L,
191L, 191L, 192L, 192L, 193L, 193L, 194L, 194L, 195L, 195L,
196L, 196L, 196L, 197L, 197L, 198L, 198L, 199L, 199L, 200L,
200L, 201L, 201L, 201L, 202L, 202L, 203L, 203L, 204L, 204L,
204L, 205L, 205L, 206L, 206L, 206L)), row.names = c(NA, -101L
), class = c("data.table", "data.frame"))
> t[175:200]
Week A B C
1: 2025-02-15 199 183 166
2: 2025-02-22 200 183 167
3: 2025-03-01 201 184 168
4: 2025-03-08 201 185 168
5: 2025-03-15 202 185 169
6: 2025-03-22 202 186 170
7: 2025-03-29 203 187 170
8: 2025-04-05 204 187 171
9: 2025-04-12 204 188 172
10: 2025-04-19 205 189 172
11: 2025-04-26 206 189 173
12: 2025-05-03 206 190 174
13: 2025-05-10 207 191 174
14: 2025-05-17 207 191 175
15: 2025-05-24 208 192 176
16: 2025-05-31 209 193 176
17: 2025-06-07 209 193 177
18: 2025-06-14 210 194 178
19: 2025-06-21 210 194 178
20: 2025-06-28 211 195 179
21: 2025-07-05 212 196 179
22: 2025-07-12 212 196 180
23: 2025-07-19 213 197 181
24: 2025-07-26 213 197 181
25: 2025-08-02 214 198 182
26: 2025-08-09 214 198 182
Функция будет принимать t
и возвращать одни и те же данные.таблица с любыми значениями, превышающими или равными наименьшему наибольшему значению, большему, чем, что target
приведет к такому выходу, когда target
имеет значение 194:
> target
[1] 194
> t[150:225]
Week A B C
1: 2024-08-24 180 163 146
2: 2024-08-31 181 164 147
3: 2024-09-07 182 165 148
4: 2024-09-14 183 166 149
5: 2024-09-21 183 166 150
6: 2024-09-28 184 167 151
7: 2024-10-05 185 168 151
8: 2024-10-12 186 169 152
9: 2024-10-19 187 170 153
10: 2024-10-26 187 171 154
11: 2024-11-02 188 171 155
12: 2024-11-09 189 172 155
13: 2024-11-16 190 173 156
14: 2024-11-23 190 174 157
15: 2024-11-30 191 175 158
16: 2024-12-07 192 175 159
17: 2024-12-14 193 176 159
18: 2024-12-21 194 177 160
19: 2024-12-28 194 178 161
20: 2025-01-04 NA 178 162
21: 2025-01-11 NA 179 162
22: 2025-01-18 NA 180 163
23: 2025-01-25 NA 181 164
24: 2025-02-01 NA 181 165
25: 2025-02-08 NA 182 165
26: 2025-02-15 NA 183 166
27: 2025-02-22 NA 183 167
28: 2025-03-01 NA 184 168
29: 2025-03-08 NA 185 168
30: 2025-03-15 NA 185 169
31: 2025-03-22 NA 186 170
32: 2025-03-29 NA 187 170
33: 2025-04-05 NA 187 171
34: 2025-04-12 NA 188 172
35: 2025-04-19 NA 189 172
36: 2025-04-26 NA 189 173
37: 2025-05-03 NA 190 174
38: 2025-05-10 NA 191 174
39: 2025-05-17 NA 191 175
40: 2025-05-24 NA 192 176
41: 2025-05-31 NA 193 176
42: 2025-06-07 NA 193 177
43: 2025-06-14 NA 194 178
44: 2025-06-21 NA 194 178
45: 2025-06-28 NA NA 179
46: 2025-07-05 NA NA 179
47: 2025-07-12 NA NA 180
48: 2025-07-19 NA NA 181
49: 2025-07-26 NA NA 181
50: 2025-08-02 NA NA 182
51: 2025-08-09 NA NA 182
52: 2025-08-16 NA NA 183
53: 2025-08-23 NA NA 184
54: 2025-08-30 NA NA 184
55: 2025-09-06 NA NA 185
56: 2025-09-13 NA NA 185
57: 2025-09-20 NA NA 186
58: 2025-09-27 NA NA 186
59: 2025-10-04 NA NA 187
60: 2025-10-11 NA NA 187
61: 2025-10-18 NA NA 188
62: 2025-10-25 NA NA 189
63: 2025-11-01 NA NA 189
64: 2025-11-08 NA NA 190
65: 2025-11-15 NA NA 190
66: 2025-11-22 NA NA 191
67: 2025-11-29 NA NA 191
68: 2025-12-06 NA NA 192
69: 2025-12-13 NA NA 192
70: 2025-12-20 NA NA 193
71: 2025-12-27 NA NA 193
72: 2026-01-03 NA NA 194
73: 2026-01-10 NA NA 194
74: 2026-01-17 NA NA NA
75: 2026-01-24 NA NA NA
76: 2026-01-31 NA NA NA
Как я могу изменить эту функцию, чтобы возвращать только первую дату после выполнения условия? Таким образом, чтобы результат выглядел так:
> t[150:225]
Week A B C
1: 2024-08-24 180 163 146
2: 2024-08-31 181 164 147
3: 2024-09-07 182 165 148
4: 2024-09-14 183 166 149
5: 2024-09-21 183 166 150
6: 2024-09-28 184 167 151
7: 2024-10-05 185 168 151
8: 2024-10-12 186 169 152
9: 2024-10-19 187 170 153
10: 2024-10-26 187 171 154
11: 2024-11-02 188 171 155
12: 2024-11-09 189 172 155
13: 2024-11-16 190 173 156
14: 2024-11-23 190 174 157
15: 2024-11-30 191 175 158
16: 2024-12-07 192 175 159
17: 2024-12-14 193 176 159
18: 2024-12-21 194 177 160
19: 2024-12-28 NA 178 161
20: 2025-01-04 NA 178 162
21: 2025-01-11 NA 179 162
22: 2025-01-18 NA 180 163
23: 2025-01-25 NA 181 164
24: 2025-02-01 NA 181 165
25: 2025-02-08 NA 182 165
26: 2025-02-15 NA 183 166
27: 2025-02-22 NA 183 167
28: 2025-03-01 NA 184 168
29: 2025-03-08 NA 185 168
30: 2025-03-15 NA 185 169
31: 2025-03-22 NA 186 170
32: 2025-03-29 NA 187 170
33: 2025-04-05 NA 187 171
34: 2025-04-12 NA 188 172
35: 2025-04-19 NA 189 172
36: 2025-04-26 NA 189 173
37: 2025-05-03 NA 190 174
38: 2025-05-10 NA 191 174
39: 2025-05-17 NA 191 175
40: 2025-05-24 NA 192 176
41: 2025-05-31 NA 193 176
42: 2025-06-07 NA 193 177
43: 2025-06-14 NA 194 178
44: 2025-06-21 NA NA 178
45: 2025-06-28 NA NA 179
46: 2025-07-05 NA NA 179
47: 2025-07-12 NA NA 180
48: 2025-07-19 NA NA 181
49: 2025-07-26 NA NA 181
50: 2025-08-02 NA NA 182
51: 2025-08-09 NA NA 182
52: 2025-08-16 NA NA 183
53: 2025-08-23 NA NA 184
54: 2025-08-30 NA NA 184
55: 2025-09-06 NA NA 185
56: 2025-09-13 NA NA 185
57: 2025-09-20 NA NA 186
58: 2025-09-27 NA NA 186
59: 2025-10-04 NA NA 187
60: 2025-10-11 NA NA 187
61: 2025-10-18 NA NA 188
62: 2025-10-25 NA NA 189
63: 2025-11-01 NA NA 189
64: 2025-11-08 NA NA 190
65: 2025-11-15 NA NA 190
66: 2025-11-22 NA NA 191
67: 2025-11-29 NA NA 191
68: 2025-12-06 NA NA 192
69: 2025-12-13 NA NA 192
70: 2025-12-20 NA NA 193
71: 2025-12-27 NA NA 193
72: 2026-01-03 NA NA 194
73: 2026-01-10 NA NA NA
74: 2026-01-17 NA NA NA
75: 2026-01-24 NA NA NA
76: 2026-01-31 NA NA NA
Ответ №1:
Возможно, что-то вроде этого:
target = 194
target.cols = c("A", "B", "C")
t[, lapply(.SD,
function(x) {x[(which.max(x>=target) 1L):length(x)] <- NA;x}),
.SDcols = target.cols]
Или, чтобы перезаписать столбцы по ссылке, сохранив столбец недели нетронутым, мы можем сделать
t[, (target.cols) := lapply(.SD,
function(x) {x[(which.max(x>=target) 1L):length(x)] <- NA; x}),
.SDcols = target.cols]
Комментарии:
1. Это работает, но на выходе получается таблица data.table без
Week
необходимого столбца. Как я могу сделать то же самое, не потеряв эту колонку?2. вам нужно сохранить исходную таблицу data.table или вы хотите просто перезаписать столбцы A:C новыми данными?
3. последнее. Второе заявление, которое вы предоставили, сделало именно то, что я искал. Спасибо!
Ответ №2:
Вариант tidyverse.
library(dplyr)
mutate(t, across(A:C, ~ if_else(. >= 194 amp;
lag(.) == 194 |
. > 194, NA_integer_, .)))
# Week A B C
# 1: 2024-08-24 180 163 146
# 2: 2024-08-31 181 164 147
# 3: 2024-09-07 182 165 148
# 4: 2024-09-14 183 166 149
# 5: 2024-09-21 183 166 150
# 6: 2024-09-28 184 167 151
# 7: 2024-10-05 185 168 151
# 8: 2024-10-12 186 169 152
# 9: 2024-10-19 187 170 153
# 10: 2024-10-26 187 171 154
# 11: 2024-11-02 188 171 155
# 12: 2024-11-09 189 172 155
# 13: 2024-11-16 190 173 156
# 14: 2024-11-23 190 174 157
# 15: 2024-11-30 191 175 158
# 16: 2024-12-07 192 175 159
# 17: 2024-12-14 193 176 159
# 18: 2024-12-21 194 177 160
# 19: 2024-12-28 NA 178 161
# 20: 2025-01-04 NA 178 162
# 21: 2025-01-11 NA 179 162
# 22: 2025-01-18 NA 180 163
# 23: 2025-01-25 NA 181 164
# 24: 2025-02-01 NA 181 165
# 25: 2025-02-08 NA 182 165
# 26: 2025-02-15 NA 183 166
# 27: 2025-02-22 NA 183 167
# 28: 2025-03-01 NA 184 168
# 29: 2025-03-08 NA 185 168
# 30: 2025-03-15 NA 185 169
# 31: 2025-03-22 NA 186 170
# 32: 2025-03-29 NA 187 170
# 33: 2025-04-05 NA 187 171
# 34: 2025-04-12 NA 188 172
# 35: 2025-04-19 NA 189 172
# 36: 2025-04-26 NA 189 173
# 37: 2025-05-03 NA 190 174
# 38: 2025-05-10 NA 191 174
# 39: 2025-05-17 NA 191 175
# 40: 2025-05-24 NA 192 176
# 41: 2025-05-31 NA 193 176
# 42: 2025-06-07 NA 193 177
# 43: 2025-06-14 NA 194 178
# 44: 2025-06-21 NA NA 178
# 45: 2025-06-28 NA NA 179
# 46: 2025-07-05 NA NA 179
# 47: 2025-07-12 NA NA 180
# 48: 2025-07-19 NA NA 181
# 49: 2025-07-26 NA NA 181
# 50: 2025-08-02 NA NA 182
# 51: 2025-08-09 NA NA 182
# 52: 2025-08-16 NA NA 183
# 53: 2025-08-23 NA NA 184
# 54: 2025-08-30 NA NA 184
# 55: 2025-09-06 NA NA 185
# 56: 2025-09-13 NA NA 185
# 57: 2025-09-20 NA NA 186
# 58: 2025-09-27 NA NA 186
# 59: 2025-10-04 NA NA 187
# 60: 2025-10-11 NA NA 187
# 61: 2025-10-18 NA NA 188
# 62: 2025-10-25 NA NA 189
# 63: 2025-11-01 NA NA 189
# 64: 2025-11-08 NA NA 190
# 65: 2025-11-15 NA NA 190
# 66: 2025-11-22 NA NA 191
# 67: 2025-11-29 NA NA 191
# 68: 2025-12-06 NA NA 192
# 69: 2025-12-13 NA NA 192
# 70: 2025-12-20 NA NA 193
# 71: 2025-12-27 NA NA 193
# 72: 2026-01-03 NA NA 194
# 73: 2026-01-10 NA NA NA
Комментарии:
1. Зачем вам использовать tidyverse в таблице data.table? Похоже, это плохая идея — перепутать пакеты.
2. @dww: Это справедливое замечание. Поскольку и вход , и выход-это а
data.table
, я не думаю, что это слишком преступно. Я бы не ожидал, что это будет принято как решение, но это может послужить пищей для размышлений.