r语言 - 如何使用数据调整代码功能以符合规范.表函数



我想改变生成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,date1date2之差为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来选择'DR'列或'date_cols'并将输出分配给这些列,然后使用行/列索引来提取值以创建'结果'

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

最新更新