R:找到条件日期的最大间隔

时间:2017-12-04 16:24:56

标签: r date

我有一个包含日期和价格的数据框。对于某些日期,价格为NA。我试图在" last"之间的日期中找到最大的间隔。 (以连续顺序)NA价格和最后非NA价格。我完全迷失了 - 我怀疑difftime需要被使用,但我无法想出这个条件。

E.g:

 DF = structure(list(rollup_date = c("2017-05-01 00:00:00", "2017-05-02 00:00:00", 
"2017-05-03 00:00:00", "2017-05-04 00:00:00", "2017-05-05 00:00:00", 
"2017-05-06 00:00:00", "2017-05-07 00:00:00", "2017-05-08 00:00:00", 
"2017-05-09 00:00:00", "2017-05-10 00:00:00", "2017-05-11 00:00:00", 
"2017-05-12 00:00:00", "2017-05-13 00:00:00", "2017-05-14 00:00:00", 
"2017-05-15 00:00:00"), RegularPrice = c(6.47, 6.47, 6.47, 6.47, 
NA, NA, NA, NA, NA, NA, NA, 6.47, NA, 6.47, 6.47)), .Names = c("rollup_date", 
"RegularPrice"), row.names = 145624:145638, class = "data.frame")

所以,这里的产出是7天(5/11 - 5/04)和1天(5月13日 - 5月5日)。可以存储所有解决方案,然后我选择最大的解决方案。

2 个答案:

答案 0 :(得分:1)

DF$rollup_date = as.POSIXct(DF$rollup_date)
with(rle(is.na(DF$RegularPrice)),
     sapply(which(values == TRUE),
            function(i) difftime(time1 = DF$rollup_date[cumsum(lengths)[i]],
                                 time2 = DF$rollup_date[cumsum(lengths)[i-1]],
                                 units = "days")))
#[1] 7 1

答案 1 :(得分:1)

为了完整起见,这里还有一个library(data.table) setDT(DF)[, rollup_date := as.Date(rollup_date)][ , .(last(RegularPrice), last(rollup_date)), by = rleid(is.na(RegularPrice))][ , diff.days := V2 - shift(V2)][ is.na(V1)] 解决方案:

   rleid V1         V2 diff.days
1:     2 NA 2017-05-11    7 days
2:     4 NA 2017-05-13    1 days
data.table

解释

强制转换为rollup_date后,Date会从字符转换为类POSIXct(此处不需要NA)。然后,使用non-NA函数按rleid()NA值的连续条纹对数据进行分组,选择每个组中的最后一个值。中间结果聚合为5行。

最后,计算每个组之间的日期差异,并仅返回rollup_date行。

前提条件

数据需要按sum()排序,这显然是OP提供的样本数据的情况,但没有明确提及。

替代解决方案

聚合仅包括挑选每组中最后一行的值。不涉及mean()DF等其他计算。这类似于过滤.I

这也可以通过返回相关的行ID DF并使用此选项从DF[, last(.I), by = rleid(is.na(RegularPrice))][, V1] 中选择相应的行来实现:

[1]  4 11 12 13 15
setDT(DF)[, rollup_date := as.Date(rollup_date)][
  DF[, last(.I), by = rleid(is.na(RegularPrice))][, V1]][
  , diff.days := rollup_date - shift(rollup_date)][
    is.na(RegularPrice)]

因此,完整的解决方案变为

   rollup_date RegularPrice diff.days
1:  2017-05-11           NA    7 days
2:  2017-05-13           NA    1 days
(function($){
$.fn.j360 = function(options) {
    var defaults = {
        clicked: false,
        currImg: 1
    }
    var options = jQuery.extend(defaults, options);
    return this.each(function() {
        var $obj = jQuery(this);
        var aImages = {};
        $obj.css({
            'margin-left' : 'auto',
            'margin-right' : 'auto',
            'text-align' : 'center',
            'overflow' : 'hide'
        });
        $overlay = $obj.clone(true);
        $overlay.html('<img src="images/loader.gif" class="loader" style="margin-top:' + ($obj.height()/2 - 15) + 'px" />');
        $overlay.attr('id', 'view_overlay');
        $overlay.css({
            'position' : 'absolute',
            'z-index': '5',
            'top' : $obj.offset().top,
            'left' : $obj.offset().left,
            'background' : '#fff'
        });
        $obj.after($overlay);
        $obj.after('<div id="colors_ctrls"></div>');
        jQuery('#colors_ctrls').css({
            'width' : $obj.width(),
            'position' : 'absolute',
            'z-index': '5',
            'top' : $obj.offset().top + $obj.height - 50,
            'left' : $obj.offset().left
        });
        var imageTotal = 0;
        jQuery('img', $obj).each(function() {
            aImages[++imageTotal] = jQuery(this).attr('src');
            preload(jQuery(this).attr('src'));
        })
        var imageCount = 0;
        jQuery('.preload_img').load(function() {
            if (++imageCount == imageTotal) {
                $overlay.animate({
                    'filter' : 'alpha(Opacity=0)',
                    'opacity' : 0
                }, 100);
                $obj.html('<img src="' + aImages[1] + '" />');
                $overlay.bind('mousedown touchstart', function(e) {
                    if (e.type == "touchstart") {
                        options.currPos = window.event.touches[0].pageX;
                    } else {
                        options.currPos = e.pageX;
                    }
                    options.clicked = true;
                    return false;
                });
                jQuery(document).bind('mouseup touchend', function() {
                    options.clicked = false;
                });
                jQuery(document).bind('mousemove touchmove', function(e) {
                    if (options.clicked) {
                        var pageX;
                        if (e.type == "touchmove") {
                            pageX = window.event.targetTouches[0].pageX;
                        } else {
                            pageX = e.pageX;
                        }
                        var width_step = 50;
                        if (Math.abs(options.currPos - pageX) >= width_step) {
                            if (options.currPos - pageX >= width_step) {
                                options.currImg++;
                                if (options.currImg > imageTotal) {
                                    options.currImg = 1;
                                }
                            } else {
                                options.currImg--;
                                if (options.currImg < 1) {
                                    options.currImg = imageTotal;
                                }
                            }
                            options.currPos = pageX;
                            $obj.html('<img src="' + aImages[options.currImg] + '" />');
                        }
                    }
                });
            }
        });
        if (jQuery.browser.msie || jQuery.browser.mozilla || jQuery.browser.opera || jQuery.browser.safari ) {
            jQuery(window).resize(function() {
                onresizeFunc($obj, $overlay);
            });
        } else {
            var supportsOrientationChange = "onorientationchange" in window,
            orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
            window.addEventListener(orientationEvent, function() {
                onresizeFunc($obj, $overlay);
            }, false);
        }
        onresizeFunc($obj, $overlay)
    });
}
})
(jQuery)


function onresizeFunc($obj, $overlay){

$obj.css({
    'margin-top' : $(document).height()/2
});
$overlay.css({
    'margin-top' : 200,
    'top' : $obj.offset().top,
    'left' : $obj.offset().left
});

jQuery('#colors_ctrls').css({
    'top' : $obj.offset().top + $obj.height - 50,
    'left' : $obj.offset().left
})
}

function preload(image) {

if (typeof document.body == "undefined") return;
try {
    var div = document.createElement("div");
    var s = div.style;
    s.position = "absolute";
    s.top = s.left = 0;
    s.visibility = "hidden";
    document.body.appendChild(div);
    div.innerHTML = "<img class=\"preload_img\" src=\"" + image + "\" />";
} 
catch(e) {
// Error. Do nothing.
}
};