2016-11-09 1 views
1

에 두 개의 열을 기반으로 XTS 인덱스로 시간 순서를 만들어가 난 할 노력하고있어 것은 나중에 사용할 수있는 열을 만드는 것입니다R은 data.frame

soc_sec group_count total_creds group_start group_end 
     (chr)  (int)  (dbl)  (date)  (date) 
1 AA2105480   5  14.0 2005-01-09 2005-05-16 
2 AA2105480   7  17.0 2004-08-26 2004-12-10 
3 AB4378973   1   0.0 2004-01-21 2004-05-07 
4 AB4990257   2   1.0 2014-09-01 2014-12-14 
5 AB7777777   5  12.0 2004-01-21 2005-03-22 
6 AB7777777   6  15.0 2004-08-26 2004-12-10 
7 AB7777777   5  15.0 2005-01-09 2005-05-12 
8 AC4285291   2   3.0 2014-09-01 2014-12-14 
9 AC4285291   1   3.0 2015-01-12 2015-04-15 
10 AC6039874   9  17.5 2010-01-06 2010-05-06 
11 AC6039874   7  16.0 2011-01-05 2011-04-29 
12 AC6039874   8  12.5 2010-08-31 2010-12-21 
13 AC6039874   7  13.5 2011-08-31 2011-12-21 
14 AC6547645   7  18.0 2005-01-09 2005-05-12 
15 AC6547645   6  17.0 2004-08-26 2004-12-10 
16 AC6547645   1   2.0 2005-04-20 2005-06-01 
17 AD1418577   7  13.0 2013-01-09 2013-05-17 
18 AD1418577   8  16.0 2013-08-28 2013-12-13 
19 AD1418577   6  15.0 2014-01-08 2014-05-05 
20 AD1418577   7  13.0 2015-08-26 2015-12-15 

아래 같은 data.frame이 group_startgroup_end 사이의 일의 순서에 따라 xts 오브젝트에 대한 날짜 별 색인으로 사용됩니다. 내가 할 수 없었습니다 무엇

df$len <- apply(df, 1, function(x){ 
    length(seq(as.Date(x["group_start"]), as.Date(x["group_end"]), by="days")) 
    }) 
df <- df[rep(seq_len(nrow(df)), df$len),] 

에 벡터화 이것이다 : 나는 내가 심지어 나중에 dplyr::bind_rows(df,v)과 수 행의 필수 반복을 할 수 v <- seq(df$group_start[1], df$group_end[1], by="days")를 사용하여 하나 개의 컬럼에 대한 벡터를 계산할 수 있어요 알고 data.frame의 각 행에 대해 발생합니다. 어떤 도움을 크게 감상 할 수 Error in seq.Date(from = as.Date(ags_df$group_start[as.integer(i)]), to = as.Date(ags_df$group_end[as.integer(i)])) : exactly two of 'to', 'by' and 'length.out'/'along.with' must be specified

:와 Error in seq.int(0, to0 - from, by) : wrong sign in 'by' argument

date_vec <- c() 
for(i in 1:nrow(df)){ 
     date_vec <- c(date_vec, seq(from=as.Date(df$group_start[as.integer(i)]), to=as.Date(df$group_end[as.integer(i)])), by="days") 
    } 

오류 :

것들 내가 함께

create_date_vector <- function(x){ 
    flog.debug("id: %s", x["soc_sec"]) 
    seq(as.Date(x["group_start"]), as.Date(x["group_end"]), by = "days") 
} 
date_vec <- c() 
date_vec <- c(date_vec, apply(df, 1, create_date_vector)) 

오류가 작동하지 않는 시도했습니다. 고맙습니다.

dput

structure(list(soc_sec = c("AA2105480", "AA2105480", "AB4378973", 
"AB4990257", "AB7777777", "AB7777777", "AB7777777", "AC4285291", 
"AC4285291", "AC6039874", "AC6039874", "AC6039874", "AC6039874", 
"AC6547645", "AC6547645", "AC6547645", "AD1418577", "AD1418577", 
"AD1418577", "AD1418577"), group_count = c(5L, 7L, 1L, 2L, 5L, 
6L, 5L, 2L, 1L, 9L, 7L, 8L, 7L, 7L, 6L, 1L, 7L, 8L, 6L, 7L), 
    total_creds = c(14, 17, 0, 1, 12, 15, 15, 3, 3, 17.5, 16, 
    12.5, 13.5, 18, 17, 2, 13, 16, 15, 13), group_start = structure(c(12792, 
    12656, 12438, 16314, 12438, 12656, 12792, 16314, 16447, 14615, 
    14979, 14852, 15217, 12792, 12656, 12893, 15714, 15945, 16078, 
    16673), class = "Date"), group_end = structure(c(12919, 12762, 
    12545, 16418, 12864, 12762, 12915, 16418, 16540, 14735, 15093, 
    14964, 15329, 12915, 12762, 12935, 15842, 16052, 16195, 16784 
    ), class = "Date")), class = c("tbl_df", "data.frame"), row.names = c(NA, 
-20L), .Names = c("soc_sec", "group_count", "total_creds", "group_start", 
"group_end")) 

답변

1

그래서, 나는 그것을 알아 내기 위해 관리하고, 난 그냥 경우에 아래로 여기에 솔루션을 두어야 그림. 여러 단계를 거쳤으므로 어느 누구보다 더 나은 방법을 생각하면 알려 주시기 바랍니다.

먼저 두 날짜 간의 일 수를 계산하는 열을 만들었습니다. 나는 각 행의 많은 반복은 다음

calc_day_nums <- function(x){ 
    if(as.numeric(as.Date(x["group_start"])) < as.numeric(as.Date(x["group_end"]))){ 
    len <- length(seq(as.Date(x["group_start"]), as.Date(x["group_end"]), by="days")) 
    } else if (as.numeric(as.Date(x["group_start"])) > as.numeric(as.Date(x["group_end"]))){ 
    len <- length(seq(as.Date(x["group_end"]), as.Date(x["group_start"]), by="days")) 
    } else { 
    len <- 1 #basically these are records whose start and end are the same 
    } 
    return(len) 
} 
df$reps <- apply(df, 1, calc_day_nums) 

을 만드는 방법을 알고 그래서 나는이 필요, 나는 그 후 자신

date_vec <- function(i, x, y){ 
    if(as.Date(x[i]) != as.Date(y[i])){ 
    as.Date(as.Date(x[i]):as.Date(y[i]), origin="1970-01-01") 
    } else{ 
    as.Date(x[i]) 
    } 
} 
vec <- lapply(seq_along(df$group_start), date_vec, x=df$group_start, y=df$group_end) 
vec <- unlist(vec) 
vec <- as.Date(vec) 

모든 일의 벡터를 생성, 나는 행의 정확한 숫자를했다 데이터에 반복. 프레임

df <- df[rep(seq_len(nrow(df)), df$reps),] 

마지막으로, 나는 벡터를 data.frame에 바인딩했다. 이 시점에서 나는 또한 단지 XTS 지수 xt <- xts(x = df, order.by = vec)vec를 정의 할 수 있지만 나는이 한 달 이상이 후에 얼마나 유용한 모르는 data.frame

df <- bind_cols(df, data.frame(days=vec)) 
3

에 추가하고 싶어 실행할 수있는 솔루션을 찾았지만 코드를 좀 더 압축 된 것으로 내려갔습니다.

library(dplyr) 

df <- structure(list(soc_sec = c("AA2105480", "AA2105480", "AB4378973", 
"AB4990257", "AB7777777", "AB7777777", "AB7777777", "AC4285291", 
"AC4285291", "AC6039874", "AC6039874", "AC6039874", "AC6039874", 
"AC6547645", "AC6547645", "AC6547645", "AD1418577", "AD1418577", 
"AD1418577", "AD1418577"), group_count = c(5L, 7L, 1L, 2L, 5L, 
6L, 5L, 2L, 1L, 9L, 7L, 8L, 7L, 7L, 6L, 1L, 7L, 8L, 6L, 7L), 
    total_creds = c(14, 17, 0, 1, 12, 15, 15, 3, 3, 17.5, 16, 
    12.5, 13.5, 18, 17, 2, 13, 16, 15, 13), group_start = structure(c(12792, 
    12656, 12438, 16314, 12438, 12656, 12792, 16314, 16447, 14615, 
    14979, 14852, 15217, 12792, 12656, 12893, 15714, 15945, 16078, 
    16673), class = "Date"), group_end = structure(c(12919, 12762, 
    12545, 16418, 12864, 12762, 12915, 16418, 16540, 14735, 15093, 
    14964, 15329, 12915, 12762, 12935, 15842, 16052, 16195, 16784 
    ), class = "Date")), .Names = c("soc_sec", "group_count", 
"total_creds", "group_start", "group_end"), class = c("tbl_df", 
"data.frame"), row.names = c(NA, -20L)) 


# Essentially the same as the calc_day_nums() and apply() part of 
# your solution. It returns an object of class difftime, but that 
# doesn't seem to cause any problems 
diffs <- abs(with(df, group_start-group_end))+1 

# This will repeat row[i] diffs[i] number of times 
df.rep <- df[rep(1:nrow(df), times=diffs), ] 
reps <- rep(diffs, times=diffs) 

# Creating the time sequences. Many ways to skin this cat, I suspect. 
# This is but one 
dates.l <- apply(
    df[colnames(df) %in% c("group_start", "group_end")], 1, 
    function(x) { 
     seq(min(as.Date(x)), max(as.Date(x)), by="days") 
    }) 

# Converting the list into one long vector. Essentially the same as 
# unlist(), except it retains the Date class. 
days <- do.call(c, dates.l) 

# Combining the elements by column 
df.long <- cbind(df.rep, reps, days) 

str(df.long) 

# dplyr isn't exactly my forte. This is just to convert the output 
# into the same tbl format as the input 
library(tibble) 
df.long <- as_tibble(df.long) 
+0

해 주셔서 감사합니다. 나는 특히 날짜 유형을 유지하는 do.call을 좋아한다. 좋은 팁. – sosukeinu