मुझे दिनांक चर "केसडेट्स" से एक नया चर "कंट्रोलडेट्स" बनाने की आवश्यकता है। इस नए वेरिएबल में वे तिथियां शामिल होंगी जो सप्ताह के एक ही दिन केसडेट के रूप में, उसी महीने और वर्ष के भीतर केस तिथि के रूप में होती हैं। उदाहरण के लिए यदि मेरे पास जुलाई के तीसरे बुधवार को केस की तारीख है तो मेरे नियंत्रण दिवस जुलाई के पहले बुधवार, जुलाई के दूसरे बुधवार और जुलाई के चौथे बुधवार होंगे। इसके अतिरिक्त, मैं बनाई गई तिथियों के प्रत्येक समूह के लिए एक संकेतक चर बनाना चाहता हूं। मैं इसे r में dplyr का उपयोग करके करना चाहता हूं।

प्रारंभिक डेटा:

Casedate
 "01-03-2015"
 "08-27-2017"
 "10-23-2019"

मैं इसे इस तरह देखना चाहता हूं

Casedate          Controldate      Index
"01-03-2015"      "01-03-2015"       1
"01-03-2015"      "01-10-2015"       1
"01-03-2015"      "01-17-2015"       1
"01-03-2015"      "01-24-2015"       1
"01-03-2015"      "01-31-2015"       1
"08-12-2017"      "08-05-2017"       2
"08-12-2017"      "08-12-2017"       2
"08-12-2017"      "08-19-2017"       2
"08-12-2017"      "08-26-2017"       2
"10-23-2019"      "10-02-2019"       3
"10-23-2019"      "10-09-2019"       3
"10-23-2019"      "10-16-2019"       3
"10-23-2019"      "10-23-2019"       3
"10-23-2019"      "10-30-2019"       3
6
Sara 28 अक्टूबर 2020, 02:21

2 जवाब

सबसे बढ़िया उत्तर

यहां tidyverse के साथ एक विकल्प दिया गया है। lubridate के साथ 'Casdate' को Date वर्ग में बदलें, फिर map वाले तत्वों पर लूप करें, list में तारीखों का एक seq बनाएं, unnest list कॉलम

library(dplyr)
library(purrr)
library(lubridate)
df1 %>% 
   mutate(Index = row_number(), 
      Casedate = mdy(Casedate), 
     wd = wday(Casedate, label = TRUE), 
     Controldate = map2(floor_date(Casedate, 'month'), wd, ~ {
   x1 <- seq(.x, length.out = 7, by = '1 day')
    seq(x1[wday(x1, label = TRUE) == .y],
       ceiling_date(.x, 'month'), by = '7 day')})) %>% 
    unnest(c(Controldate)) %>%
    select(Casedate, Controldate, Index)

आउटपुट

# A tibble: 14 x 3
#   Casedate   Controldate Index
#   <date>     <date>      <int>
# 1 2015-01-03 2015-01-03      1
# 2 2015-01-03 2015-01-10      1
# 3 2015-01-03 2015-01-17      1
# 4 2015-01-03 2015-01-24      1
# 5 2015-01-03 2015-01-31      1
# 6 2017-08-27 2017-08-06      2
# 7 2017-08-27 2017-08-13      2
# 8 2017-08-27 2017-08-20      2
# 9 2017-08-27 2017-08-27      2
#10 2019-10-23 2019-10-02      3
#11 2019-10-23 2019-10-09      3
#12 2019-10-23 2019-10-16      3
#13 2019-10-23 2019-10-23      3
#14 2019-10-23 2019-10-30      3

आंकड़े

df1 <- structure(list(Casedate = c("01-03-2015", "08-27-2017", "10-23-2019"
)), class = "data.frame", row.names = c(NA, -3L))
1
akrun 28 अक्टूबर 2020, 02:48

चूंकि एक महीने के भीतर अधिकतम 4 सप्ताह पहले या 4 सप्ताह बाद हो सकता है (कुल 9 मान), आप कुछ अनुक्रमों के साथ एक ही बार में उस सीमा की गणना कर सकते हैं। यह स्पष्ट रूप से प्रत्येक मूल्य पर लूपिंग की आवश्यकता से बचना चाहिए।

मानों की गणना करने के बाद, एक ही स्वीप में मूल मान के रूप में उसी महीने में उन पर सबसेट करें। नीचे से @akrun के df1 उदाहरण डेटा का उपयोग करना:

d  <- as.Date(df1$Casedate, format="%m-%d-%Y")
r  <- rep(d, each=9)
o  <- r + (7 * -4:4)
i  <- rep(seq_along(d), each=9)
s  <- format(o, "%m") == format(r, "%m")

data.frame(
    Casedate = r,
    Controldate = o,
    Index = i
)[s,]

#     Casedate Controldate Index
#5  2015-01-03  2015-01-03     1
#6  2015-01-03  2015-01-10     1
#7  2015-01-03  2015-01-17     1
#8  2015-01-03  2015-01-24     1
#9  2015-01-03  2015-01-31     1
#11 2017-08-27  2017-08-06     2
#12 2017-08-27  2017-08-13     2
#13 2017-08-27  2017-08-20     2
#14 2017-08-27  2017-08-27     2
#20 2019-10-23  2019-10-02     3
#21 2019-10-23  2019-10-09     3
#22 2019-10-23  2019-10-16     3
#23 2019-10-23  2019-10-23     3
#24 2019-10-23  2019-10-30     3

यदि आप डेटासेट में सभी मूल चर रखना चाहते हैं, तो यह एक आसान समाधान है:

cbind(
  df1[i,],
  data.frame(Controldate = o, Index = i)
)[s,]

उदा.:

#      Casedate othvar1 othvar2 Controldate Index
#1.4 01-03-2015       a       B  2015-01-03     1
#1.5 01-03-2015       a       B  2015-01-10     1
#1.6 01-03-2015       a       B  2015-01-17     1
#1.7 01-03-2015       a       B  2015-01-24     1
#...

मामूली बड़े डेटासेट (300K पंक्तियों) पर भी, अनुक्रम रन (2 सेकंड) उत्पन्न करने और प्रत्येक मान (2 मिनट) पर लूपिंग के बीच के समय में एक सार्थक अंतर है:

अनुक्रम:

df1 <- df1[rep(1:3,each=1e5),,drop=FALSE]

system.time({
d  <- as.Date(df1$Casedate, format="%m-%d-%Y")
r  <- rep(d, each=9)
o  <- r + (7 * -4:4)
i  <- rep(seq_along(d), each=9)
s  <- format(o, "%m") == format(r, "%m")

data.frame(
    Casedate = r,
    Controldate = o,
    Index = i
)[s,]
})

#   user  system elapsed 
#  1.909   0.128   2.038 

लूपिंग:

library(dplyr)
library(purrr)
library(lubridate)

system.time({
df1 %>% 
   mutate(Index = row_number(), 
      Casedate = mdy(Casedate), 
     wd = wday(Casedate, label = TRUE), 
     Controldate = map2(floor_date(Casedate, 'month'), wd, ~ {
   x1 <- seq(.x, length.out = 7, by = '1 day')
    seq(x1[wday(x1, label = TRUE) == .y],
       ceiling_date(.x, 'month'), by = '7 day')})) %>% 
    unnest(Controldate) %>%
    select(Casedate, Controldate, Index)
})

#    user  system elapsed 
# 131.466   1.143 132.623
1
thelatemail 29 अक्टूबर 2020, 01:31