如何使用 data.table 函数根据规范调整代码功能
How adjust code functionality to specifications using data.table function
我想更改生成 Output
的方法。是否可以在下面的这种情况下使用 data.table
函数?如果是的话,你能帮我调整一下吗?我在下面插入了一个已完成计算的示例。下面的代码来自一个已经解决的问题:
library(dplyr)
library(tidyverse)
library(lubridate)
df1 <- structure(list(date1 = c("2021-06-28"),
date2 = c("2021-06-30"),
Category = c("FDE"),
Week = c("Wednesday"),
DR1 = c(4), DRM001 = c(4), DRM002 = c(2),
DRM003 = c(9), DRM004 = c(5), DRM005 = c(5),
DRM006 = c(2),DRM007 = c(1),
coef = c(8)), class = "data.frame", row.names = c(NA, -1L))
Output<-df1 %>%
mutate(across(starts_with("DR"), ~ coef - .),
across(contains("date"), ymd),
datedif = parse_number(as.character(date2-date1))
) %>%
rename_with(~str_replace(.,'(?<=[A-Z])0+(?=.)', ""),starts_with('DR')) %>%
rowwise %>%
mutate(Result = if (str_c('DRM', datedif) %in% names(.)) get(str_c('DRM', datedif)) else coef) %>%
ungroup() %>%
select(coef, Result)%>%data.frame()
> Output
coef Result
1 8 6
例如:看到coef
是8,date1
和date2
的差是2,所以Result
等于coef - DRM2
。如果日期之间的差异是 3 那么它将是 Result = coef - DRM3
date1 date2 Category Week DR1 DRM1 DRM2 DRM3 DRM4 DRM5 DRM6 DRM7 coef datedif
1 2021-06-28 2021-06-30 FDE Wednesday 4 4 6 -1 3 3 6 7 8 2
检查:
df1<-structure(list(Id = 8, date1 = structure(19090L, class = c("IDate",
"Date")), date2 = structure(19090L, class = c("IDate",
"Date")), Week = "Sexta-feira", DT = "0", Category = "PUBBAR",
GR = 1, DR1 = 14, DayM = 1, DayM1 = 1, DayM2 = 0,
DayM3 = 0, DayM4 = 1, DayM5 = 1, DayM6 = 1, DayM7 = 2, DayM8 = 2,
DayM9 = 2, DayM10 = 2, DayM11 = 4, DayM12 = 4, DayM13 = 4,
DayM14 = 4, DayM15 = 4, DayM16 = 4, DayM17 = 4, DayM18 = 4,
DayM19 = 4, DayM20 = 6, DayM21 = 6, DayM22 = 8, DayM23 = 8,
DayM24 = 8, DayM25 = 8, DayM26 = 8, DayM27 = 8, DayM28 = 8,
DayM29 = 8, DayM30 = 8, DayM31 = 10, DayM32 = 10, DayM33 = 10,
DayM34 = 10, DayM35 = 10, DayM36 = 10, DayM37 = 9, DayM38 = 9,
DayM39 = 9, DayM40 = 9, DayM41 = 9, DayM42 = 9, DayM43 = 9,
DayM44 = 9, DayM45 = 9, DayM46 = 9, DayM47 = 9, DayM48 = 9,
DayM49 = 9, DayM50 = 10, DayM51 = 10, DayM52 = 10, DayM53 = 10,
DayM54 = 10, DayM55 = 10, DayM56 = 10, DayM57 = 10, DayM58 = 10,
DayM59 = 10, DayM60 = 10, DayM61 = 10, DayM62 = 10, DayM63 = 10,
DayM64 = 10, DayM65 = 10, DayM66 = 10, DayM67 = 10, DayM68 = 10,
DayM69 = 10, DayM70 = 10, DayM71 = 10, DayM72 = 10, DayM73 = 10,
DayM74 = 10, DayM75 = 10, DayM76 = 10, DayM77 = 10, DayM78 = 10,
DayM79 = 10, DayM80 = 10, DayM81 = 10, DayM82 = 10, DayM83 = 10,
DayM84 = 10, DayM85 = 10, DayM86 = 10, DayM87 = 10, DayM88 = 10,
DayM89 = 10, DayM90 = 10, DayM91 = 10, DayM92 = 10, DayM93 = 10,
DayM94 = 10, DayM95 = 10, DayM96 = 10, DayM97 = 10, DayM98 = 10,
DayM99 = 10, DayM100 = 10, DayM101 = 10, DayM102 = 10, DayM103 = 10,
DayM104 = 10, DayM105 = 10, DayM106 = 10, DayM107 = 10, DayM108 = 10,
DayM109 = 10, DayM110 = 10, DayM111 = 10, DayM112 = 10, DayM113 = 10,
DayM114 = 10, DayM115 = 10, DayM116 = 10, DayM117 = 10, DayM118 = 10,
DayM119 = 10, DayM120 = 10, DayM121 = 10, DayM122 = 10, DayM123 = 10,
DayM124 = 10, DayM125 = 10, DayM126 = 10, DayM127 = 10, DayM128 = 10,
DayM129 = 10, DayM130 = 10, DayM131 = 12, DayM132 = 12, DayM133 = 12,
DayM134 = 12, DayM135 = 12, DayM136 = 12, DayM137 = 12, DayM138 = 12,
DayM139 = 12, DayM140 = 12, DayM141 = 12, DayM142 = 12, DayM143 = 12,
DayM144 = 12, DayM145 = 13, DayM146 = 13, DayM147 = 13, DayM148 = 13,
DayM149 = 13, DayM150 = 13, DayM151 = 13, DayM152 = 13, DayM153 = 14,
DayM154 = 14, DayM155 = 14, DayM156 = 14, DayM157 = 14, DayM158 = 14,
DayM159 = 14, DayM160 = 14, DayM161 = 14, DayM162 = 14, DayM163 = 14,
DayM164 = 14, DayM165 = 14, DayM166 = 14, DayM167 = 14, DayM168 = 14,
DayM169 = 14, DayM170 = 14, DayM171 = 14, DayM172 = 14, DayM173 = 14,
DayM174 = 14, DayM175 = 14, DayM176 = 14, DayM177 = 14, DayM178 = 14,
DayM179 = 14, DayM180 = 14, DayM181 = 14, DayM182 = 14, DayM183 = 14,
DayM184 = 14, DayM185 = 14, DayM186 = 14, DayM187 = 14, DayM188 = 14,
DayM189 = 14, DayM190 = 14, DayM191 = 14, DayM192 = 14, DayM193 = 14,
DayM194 = 14, DayM195 = 14, DayM196 = 14, DayM197 = 14, DayM198 = 14,
DayM199 = 14, DayM200 = 14, DayM201 = 14, DayM202 = 14, DayM203 = 14,
DayM204 = 14, DayM205 = 14, DayM206 = 14, DayM207 = 14, DayM208 = 14,
DayM209 = 14, DayM210 = 14, DayM211 = 14, DayM212 = 14, DayM213 = 14,
DayM214 = 14, DayM215 = 14, DayM216 = 14, DayM217 = 14, DayM218 = 14,
DayM219 = 14, DayM220 = 14, DayM221 = 14, DayM222 = 14, DayM223 = 14,
DayM224 = 14, DayM225 = 14, DayM226 = 14, DayM227 = 14, DayM228 = 14,
DayM229 = 14, DayM230 = 14, DayM231 = 14, DayM232 = 14, DayM233 = 14,
DayM234 = 14, DayM235 = 14, DayM236 = 14, DayM237 = 14, DayM238 = 14,
DayM239 = 14, DayM240 = 14, DayM241 = 14, DayM242 = 14, DayM243 = 14,
DayM244 = 14, DayM245 = 14, DayM246 = 14, DayM247 = 14, DayM248 = 14,
DayM249 = 14, DayM250 = 14, DayM251 = 14, DayM252 = 14, DayM253 = 14,
DayM254 = 14, DayM255 = 14, DayM256 = 14, DayM257 = 14, DayM258 = 14,
DayM259 = 14, DayM260 = 14, DayM261 = 14, DayM262 = 14, DayM263 = 14,
DayM264 = 14, DayM265 = 14, DayM266 = 14, DayM267 = 14, DayM268 = 14,
DayM269 = 14, DayM270 = 14, DayM271 = 14, DayM272 = 14, DayM273 = 14,
DayM274 = 14, DayM275 = 14, DayM276 = 14, DayM277 = 14, DayM278 = 14,
DayM279 = 14, DayM280 = 14, DayM281 = 14, DayM282 = 14, DayM283 = 14,
DayM284 = 14, DayM285 = 14, DayM286 = 14, DayM287 = 14, DayM288 = 14,
DayM289 = 14, DayM290 = 14, DayM291 = 14, DayM292 = 14, DayM293 = 14,
DayM294 = 14, DayM295 = 14, DayM296 = 14, DayM297 = 14, DayM298 = 14,
DayM299 = 14, DayM300 = 14, DayM301 = 14, DayM302 = 14, DayM303 = 14,
DayM304 = 14, DayM305 = 14, DayM306 = 14, DayM307 = 14, DayM308 = 14,
DayM309 = 14, DayM310 = 14, DayM311 = 14, DayM312 = 14, DayM313 = 14,
DayM314 = 14, DayM315 = 14, DayM316 = 14, DayM317 = 14, DayM318 = 14,
DayM319 = 14, DayM320 = 14, DayM321 = 14, DayM322 = 14, DayM323 = 14,
DayM324 = 14, DayM325 = 14, DayM326 = 14, DayM327 = 14, DayM328 = 14,
DayM329 = 14, DayM330 = 14, DayM331 = 14, DayM332 = 14, DayM333 = 14,
DayM334 = 14, DayM335 = 14, DayM336 = 14, DayM337 = 14, DayM338 = 14,
DayM339 = 14, DayM340 = 14, DayM341 = 14, DayM342 = 14, DayM343 = 14,
DayM344 = 14, DayM345 = 14, DayM346 = 14, DayM347 = 14, DayM348 = 14,
DayM349 = 14, DayM350 = 14, DayM351 = 14, DayM352 = 14, DayM353 = 14,
DayM354 = 14, DayM355 = 14, DayM356 = 14, DayM357 = 14, DayM358 = 14,
DayM359 = 14, DayM360 = 14, DayM361 = 14, DayM362 = 14, DayM363 = 14,
DayM364 = 14, DayM365 = 14, coef = 14, datedif = 0L), class = "data.frame", row.names = c(NA,
-1L))
df1<-as.data.table(df1)
Output2 <- df1[, .(coef, Result = fcoalesce(as.matrix(.SD)[cbind(.I, match(paste0('DayM', datedif), names(.SD)))], coef)), .SDcols = patterns("^DayM\d+")]
> Output2
coef Result
1: 14 14
结果是 coef - DayM
= 14 - 1 = 13
使用 data.table
,我们可以将 .SDcols
指定为 select 'DR' 列或 'date_cols' 并将输出分配回那些,然后改为使用按行匹配,使用 row/column 索引提取值以创建 'Result'
library(data.table)
# get the column names that starts with DR
dr_names <- grep("^DR", names(df1), value = TRUE)
# get the columns that contains date as substring
date_names <- grep("date", names(df1), value = TRUE)
# setDT - converts the data.frame to data.table
# .SDcols - specify the dr_names, date_names, loop over those
# with lapply, apply the functions and assign (`:=`) back to
# same columns
setDT(df1)[, (dr_names) := lapply(.SD, function(x) coef - x), .SDcols = dr_names
][, (date_names) := lapply(.SD, as.IDate), .SDcols = date_names
][, datedif := date2 - date1]
# rename with setnames
setnames(df1, dr_names, sub("([A-Z])0+", "\1", dr_names))
# Extract the corresponding 'DRM' column based on the value from
# datediff and match it with the DRM column names
# using a row/column indexing
# return the Result and coef columns
Output2 <- df1[, .(coef, Result = as.matrix(.SD)[cbind(.I,
match(paste0('DRM', datedif), names(.SD)))]),
.SDcols = patterns("^DRM\d+")]
Output2[is.na(Result), Result := coef]
-输出
> Output2
coef Result
<num> <num>
1: 8 6
我想更改生成 Output
的方法。是否可以在下面的这种情况下使用 data.table
函数?如果是的话,你能帮我调整一下吗?我在下面插入了一个已完成计算的示例。下面的代码来自一个已经解决的问题:
library(dplyr)
library(tidyverse)
library(lubridate)
df1 <- structure(list(date1 = c("2021-06-28"),
date2 = c("2021-06-30"),
Category = c("FDE"),
Week = c("Wednesday"),
DR1 = c(4), DRM001 = c(4), DRM002 = c(2),
DRM003 = c(9), DRM004 = c(5), DRM005 = c(5),
DRM006 = c(2),DRM007 = c(1),
coef = c(8)), class = "data.frame", row.names = c(NA, -1L))
Output<-df1 %>%
mutate(across(starts_with("DR"), ~ coef - .),
across(contains("date"), ymd),
datedif = parse_number(as.character(date2-date1))
) %>%
rename_with(~str_replace(.,'(?<=[A-Z])0+(?=.)', ""),starts_with('DR')) %>%
rowwise %>%
mutate(Result = if (str_c('DRM', datedif) %in% names(.)) get(str_c('DRM', datedif)) else coef) %>%
ungroup() %>%
select(coef, Result)%>%data.frame()
> Output
coef Result
1 8 6
例如:看到coef
是8,date1
和date2
的差是2,所以Result
等于coef - DRM2
。如果日期之间的差异是 3 那么它将是 Result = coef - DRM3
date1 date2 Category Week DR1 DRM1 DRM2 DRM3 DRM4 DRM5 DRM6 DRM7 coef datedif
1 2021-06-28 2021-06-30 FDE Wednesday 4 4 6 -1 3 3 6 7 8 2
检查:
df1<-structure(list(Id = 8, date1 = structure(19090L, class = c("IDate",
"Date")), date2 = structure(19090L, class = c("IDate",
"Date")), Week = "Sexta-feira", DT = "0", Category = "PUBBAR",
GR = 1, DR1 = 14, DayM = 1, DayM1 = 1, DayM2 = 0,
DayM3 = 0, DayM4 = 1, DayM5 = 1, DayM6 = 1, DayM7 = 2, DayM8 = 2,
DayM9 = 2, DayM10 = 2, DayM11 = 4, DayM12 = 4, DayM13 = 4,
DayM14 = 4, DayM15 = 4, DayM16 = 4, DayM17 = 4, DayM18 = 4,
DayM19 = 4, DayM20 = 6, DayM21 = 6, DayM22 = 8, DayM23 = 8,
DayM24 = 8, DayM25 = 8, DayM26 = 8, DayM27 = 8, DayM28 = 8,
DayM29 = 8, DayM30 = 8, DayM31 = 10, DayM32 = 10, DayM33 = 10,
DayM34 = 10, DayM35 = 10, DayM36 = 10, DayM37 = 9, DayM38 = 9,
DayM39 = 9, DayM40 = 9, DayM41 = 9, DayM42 = 9, DayM43 = 9,
DayM44 = 9, DayM45 = 9, DayM46 = 9, DayM47 = 9, DayM48 = 9,
DayM49 = 9, DayM50 = 10, DayM51 = 10, DayM52 = 10, DayM53 = 10,
DayM54 = 10, DayM55 = 10, DayM56 = 10, DayM57 = 10, DayM58 = 10,
DayM59 = 10, DayM60 = 10, DayM61 = 10, DayM62 = 10, DayM63 = 10,
DayM64 = 10, DayM65 = 10, DayM66 = 10, DayM67 = 10, DayM68 = 10,
DayM69 = 10, DayM70 = 10, DayM71 = 10, DayM72 = 10, DayM73 = 10,
DayM74 = 10, DayM75 = 10, DayM76 = 10, DayM77 = 10, DayM78 = 10,
DayM79 = 10, DayM80 = 10, DayM81 = 10, DayM82 = 10, DayM83 = 10,
DayM84 = 10, DayM85 = 10, DayM86 = 10, DayM87 = 10, DayM88 = 10,
DayM89 = 10, DayM90 = 10, DayM91 = 10, DayM92 = 10, DayM93 = 10,
DayM94 = 10, DayM95 = 10, DayM96 = 10, DayM97 = 10, DayM98 = 10,
DayM99 = 10, DayM100 = 10, DayM101 = 10, DayM102 = 10, DayM103 = 10,
DayM104 = 10, DayM105 = 10, DayM106 = 10, DayM107 = 10, DayM108 = 10,
DayM109 = 10, DayM110 = 10, DayM111 = 10, DayM112 = 10, DayM113 = 10,
DayM114 = 10, DayM115 = 10, DayM116 = 10, DayM117 = 10, DayM118 = 10,
DayM119 = 10, DayM120 = 10, DayM121 = 10, DayM122 = 10, DayM123 = 10,
DayM124 = 10, DayM125 = 10, DayM126 = 10, DayM127 = 10, DayM128 = 10,
DayM129 = 10, DayM130 = 10, DayM131 = 12, DayM132 = 12, DayM133 = 12,
DayM134 = 12, DayM135 = 12, DayM136 = 12, DayM137 = 12, DayM138 = 12,
DayM139 = 12, DayM140 = 12, DayM141 = 12, DayM142 = 12, DayM143 = 12,
DayM144 = 12, DayM145 = 13, DayM146 = 13, DayM147 = 13, DayM148 = 13,
DayM149 = 13, DayM150 = 13, DayM151 = 13, DayM152 = 13, DayM153 = 14,
DayM154 = 14, DayM155 = 14, DayM156 = 14, DayM157 = 14, DayM158 = 14,
DayM159 = 14, DayM160 = 14, DayM161 = 14, DayM162 = 14, DayM163 = 14,
DayM164 = 14, DayM165 = 14, DayM166 = 14, DayM167 = 14, DayM168 = 14,
DayM169 = 14, DayM170 = 14, DayM171 = 14, DayM172 = 14, DayM173 = 14,
DayM174 = 14, DayM175 = 14, DayM176 = 14, DayM177 = 14, DayM178 = 14,
DayM179 = 14, DayM180 = 14, DayM181 = 14, DayM182 = 14, DayM183 = 14,
DayM184 = 14, DayM185 = 14, DayM186 = 14, DayM187 = 14, DayM188 = 14,
DayM189 = 14, DayM190 = 14, DayM191 = 14, DayM192 = 14, DayM193 = 14,
DayM194 = 14, DayM195 = 14, DayM196 = 14, DayM197 = 14, DayM198 = 14,
DayM199 = 14, DayM200 = 14, DayM201 = 14, DayM202 = 14, DayM203 = 14,
DayM204 = 14, DayM205 = 14, DayM206 = 14, DayM207 = 14, DayM208 = 14,
DayM209 = 14, DayM210 = 14, DayM211 = 14, DayM212 = 14, DayM213 = 14,
DayM214 = 14, DayM215 = 14, DayM216 = 14, DayM217 = 14, DayM218 = 14,
DayM219 = 14, DayM220 = 14, DayM221 = 14, DayM222 = 14, DayM223 = 14,
DayM224 = 14, DayM225 = 14, DayM226 = 14, DayM227 = 14, DayM228 = 14,
DayM229 = 14, DayM230 = 14, DayM231 = 14, DayM232 = 14, DayM233 = 14,
DayM234 = 14, DayM235 = 14, DayM236 = 14, DayM237 = 14, DayM238 = 14,
DayM239 = 14, DayM240 = 14, DayM241 = 14, DayM242 = 14, DayM243 = 14,
DayM244 = 14, DayM245 = 14, DayM246 = 14, DayM247 = 14, DayM248 = 14,
DayM249 = 14, DayM250 = 14, DayM251 = 14, DayM252 = 14, DayM253 = 14,
DayM254 = 14, DayM255 = 14, DayM256 = 14, DayM257 = 14, DayM258 = 14,
DayM259 = 14, DayM260 = 14, DayM261 = 14, DayM262 = 14, DayM263 = 14,
DayM264 = 14, DayM265 = 14, DayM266 = 14, DayM267 = 14, DayM268 = 14,
DayM269 = 14, DayM270 = 14, DayM271 = 14, DayM272 = 14, DayM273 = 14,
DayM274 = 14, DayM275 = 14, DayM276 = 14, DayM277 = 14, DayM278 = 14,
DayM279 = 14, DayM280 = 14, DayM281 = 14, DayM282 = 14, DayM283 = 14,
DayM284 = 14, DayM285 = 14, DayM286 = 14, DayM287 = 14, DayM288 = 14,
DayM289 = 14, DayM290 = 14, DayM291 = 14, DayM292 = 14, DayM293 = 14,
DayM294 = 14, DayM295 = 14, DayM296 = 14, DayM297 = 14, DayM298 = 14,
DayM299 = 14, DayM300 = 14, DayM301 = 14, DayM302 = 14, DayM303 = 14,
DayM304 = 14, DayM305 = 14, DayM306 = 14, DayM307 = 14, DayM308 = 14,
DayM309 = 14, DayM310 = 14, DayM311 = 14, DayM312 = 14, DayM313 = 14,
DayM314 = 14, DayM315 = 14, DayM316 = 14, DayM317 = 14, DayM318 = 14,
DayM319 = 14, DayM320 = 14, DayM321 = 14, DayM322 = 14, DayM323 = 14,
DayM324 = 14, DayM325 = 14, DayM326 = 14, DayM327 = 14, DayM328 = 14,
DayM329 = 14, DayM330 = 14, DayM331 = 14, DayM332 = 14, DayM333 = 14,
DayM334 = 14, DayM335 = 14, DayM336 = 14, DayM337 = 14, DayM338 = 14,
DayM339 = 14, DayM340 = 14, DayM341 = 14, DayM342 = 14, DayM343 = 14,
DayM344 = 14, DayM345 = 14, DayM346 = 14, DayM347 = 14, DayM348 = 14,
DayM349 = 14, DayM350 = 14, DayM351 = 14, DayM352 = 14, DayM353 = 14,
DayM354 = 14, DayM355 = 14, DayM356 = 14, DayM357 = 14, DayM358 = 14,
DayM359 = 14, DayM360 = 14, DayM361 = 14, DayM362 = 14, DayM363 = 14,
DayM364 = 14, DayM365 = 14, coef = 14, datedif = 0L), class = "data.frame", row.names = c(NA,
-1L))
df1<-as.data.table(df1)
Output2 <- df1[, .(coef, Result = fcoalesce(as.matrix(.SD)[cbind(.I, match(paste0('DayM', datedif), names(.SD)))], coef)), .SDcols = patterns("^DayM\d+")]
> Output2
coef Result
1: 14 14
结果是 coef - DayM
= 14 - 1 = 13
使用 data.table
,我们可以将 .SDcols
指定为 select 'DR' 列或 'date_cols' 并将输出分配回那些,然后改为使用按行匹配,使用 row/column 索引提取值以创建 'Result'
library(data.table)
# get the column names that starts with DR
dr_names <- grep("^DR", names(df1), value = TRUE)
# get the columns that contains date as substring
date_names <- grep("date", names(df1), value = TRUE)
# setDT - converts the data.frame to data.table
# .SDcols - specify the dr_names, date_names, loop over those
# with lapply, apply the functions and assign (`:=`) back to
# same columns
setDT(df1)[, (dr_names) := lapply(.SD, function(x) coef - x), .SDcols = dr_names
][, (date_names) := lapply(.SD, as.IDate), .SDcols = date_names
][, datedif := date2 - date1]
# rename with setnames
setnames(df1, dr_names, sub("([A-Z])0+", "\1", dr_names))
# Extract the corresponding 'DRM' column based on the value from
# datediff and match it with the DRM column names
# using a row/column indexing
# return the Result and coef columns
Output2 <- df1[, .(coef, Result = as.matrix(.SD)[cbind(.I,
match(paste0('DRM', datedif), names(.SD)))]),
.SDcols = patterns("^DRM\d+")]
Output2[is.na(Result), Result := coef]
-输出
> Output2
coef Result
<num> <num>
1: 8 6