我正在寻找使用data.table的解决方案―我有一个data.table,其中包含以下列:
data <- data.frame(GROUP=c(3,3,4,4,5,6),
YEAR=c(1979,1985,1999,2011,2012,1994),
NAME=c("S","A","J","L","G","A"))
data <- as.data.table(data)
Data.table:
GROUP YEAR NAME
3 1979 Smith
3 1985 Anderson
4 1999 James
4 2011 Liam
5 2012 George
6 1994 Adams
对于每个组,我们要使用以下规则选择一行:
所需的输出:
GROUP YEAR NAME
3 1985 Anderson
4 2011 Liam
5 2012 George
6 1994 Adams
谢谢!我已经为此苦了一段时间。
答案 0 :(得分:5)
data.table
行计数器作为子集,则 .I
应该简单得多:
library(data.table)
setDT(data)
data[
data[
,
if(any(YEAR > 2000))
.I[which.min(2000 - YEAR)] else
.I[which.max(YEAR)],
by=GROUP
]$V1
]
# GROUP YEAR NAME
#1: 3 1985 A
#2: 4 2011 L
#3: 5 2012 G
#4: 6 1994 A
感谢@ r2evans提供背景信息-
.I
是一个等效于seq_len(nrow(x))
的整数矢量。
参考: http://rdrr.io/cran/data.table/man/special-symbols.html
因此,我在这里要做的就是为每个data
级别上的每个计算获取整个by=
的匹配行索引。然后,使用这些行索引再次子集data
。
答案 1 :(得分:3)
您还可以进行几次滚动连接:
res = unique(data[, .(GROUP)])
# get row with YEAR above 2000
res[, w := data[c(.SD, YEAR = 2000), on=.(GROUP, YEAR), roll=-Inf, which=TRUE]]
# if none found, get row with nearest YEAR below
res[is.na(w), w := data[c(.SD, YEAR = 2000), on=.(GROUP, YEAR), roll=Inf, which=TRUE]]
# subset by row numbers
data[res$w]
GROUP YEAR NAME
1: 3 1985 A
2: 4 2011 L
3: 5 2012 G
4: 6 1994 A
答案 2 :(得分:2)
使用dplyr
包,我得到这样的输出(尽管这可能不是最简单的答案):
library(dplyr)
library(magrittr)
data <- data.frame(GROUP=c(3,3,4,4,5,6),
YEAR=c(1979,1985,1999,2011,2012,1994),
NAME=c("S","A","J","L","G","A"))
data %>%
subset(YEAR < 2000) %>%
group_by(GROUP) %>%
summarise(MAX=max(YEAR)) %>%
join(data %>%
subset(YEAR > 2000) %>%
group_by(GROUP) %>%
summarise(MIN=min(YEAR)), type="full") %>%
mutate(YEAR=ifelse(is.na(MIN), MAX, MIN)) %>%
select(c(GROUP, YEAR)) %>%
join(data)
结果:
GROUP YEAR NAME
3 1985 A
4 2011 L
5 2012 G
6 1994 A
编辑:对不起,我的第一个答案没有考虑最小/最大条件。希望这会有所帮助