子集数据-比平时更难

时间:2018-08-02 14:52:12

标签: r if-statement dataframe subset

我有一个数据集,其中包含来自不同年份的观测结果。观察并没有在同一年开始,也就是说,有些开始于1996年,有些开始于2008年。

Element 1 | 4.1 | 2018
Element 1 | 3.9 | 2017
Element 1 | 3.4 | 2016   
..........|.....| ....    
Element 1 | 2.1 | 1996 
Element 2 | 2.1 | 2018
Element 2 | 1.0 | 2017
..........|.....| ....
Element 2 | 1.0 | 2008

现在,我想要一个仅包含从2006年开始的观测值的列表。这意味着该列表将包含元素1,但不包含元素2。

我的第一种方法是使用命令

subset(mydata, year > 2006)

但是这没有用,因为它包括从2008年开始的元素2。我被困在这里。我想告诉R仅在满足2006年至2018年间观测到元素的条件的情况下才对数据进行子集化。我应该如何处理?

2 个答案:

答案 0 :(得分:1)

仅使用基数R:

newdata <- lapply(split(mydata, mydata$group),
                  subset, year > 2006 & any(year <= 2006))
newdata <- do.call(rbind, newdata)

row.names(newdata) <- NULL
newdata
#    group value year
#1 Element 1   4.1 2018
#2 Element 1   3.9 2017
#3 Element 1   3.4 2016

数据。

mydata <-
structure(list(group = c("Element 1", "Element 1", "Element 1", 
"Element 1", "Element 2", "Element 2", "Element 2"), value = c("4.1", 
"3.9", "3.4", "2.1", "2.1", "1", "1"), year = c("2018", "2017", 
"2016", "1996", "2018", "2017", "2008")), row.names = c(NA, -7L
), class = "data.frame")

答案 1 :(得分:0)

lapply语句将检查每个元素,以确保每个年份都有观测结果。如果每年都考虑在内,它将返回该元素的group名称,您可以使用该名称来使用常规方括号表示法选择包含该元素的行:

elements <- unlist(lapply(unique(mydata$group), function(x) {
    if (all(c(1996, 2016, 2017, 2018) %in% mydata[mydata$group == x, 'year'])) {
        return(x)
    }
}))

mydata[mydata$group %in% elements, ]

      group value year
1 Element 1   4.1 2018
2 Element 1   3.9 2017
3 Element 1   3.4 2016
4 Element 1   2.1 1996

或者,如果您只想返回2006年之后的年份:

mydata[mydata$group %in% elements & mydata$year > 2006, ]

      group value year
1 Element 1   4.1 2018
2 Element 1   3.9 2017
3 Element 1   3.4 2016

在最终模型中,只需将年份列表替换为:

seq.int(2006, 2018)

以获取2006年至2018年之间所有年份的列表。在本示例中,我将其限制为因为示例数据仅显示了年份的子集

要进行匹配,元素必须在年份列表中的每一年都具有观测值,但是具有额外的年份(例如,如果Element1也具有1934年的观测值)则不是问题。

如果您颠倒%in%表达式的顺序,它将检查以确保元素集中的每一年都以年份表示(但是缺少年份不是问题)

要确保这两个条件,只需使用&来加入2条语句。

数据:

mydata <- structure(list(group = c("Element 1", "Element 1", "Element 1",
                                   "Element 1", "Element 2", "Element 2", "Element 2"),
                         value = c("4.1","3.9", "3.4", "2.1", "2.1", "1", "1"),
                         year = c("2018", "2017","2016", "1996", "2018", "2017", "2008")),
                    row.names = c(NA, -7L), class = "data.frame")