我有一个数据集,其中包含来自不同年份的观测结果。观察并没有在同一年开始,也就是说,有些开始于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年间观测到元素的条件的情况下才对数据进行子集化。我应该如何处理?
答案 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")