簡體   English   中英

R data.table 在組內查找最小值和最大值

[英]R data.table finding min and max within groups

嗨,我有一個數據集,其中一個人在不同的公司工作,我遇到了這個問題。 現在我想找到他工作的每家公司的持續時間。 有些人回到他以前的公司工作。 這是我的數據集和我的實現,但是當他以后回到他以前的公司時它不起作用。

library(data.table)
data <- data.table(person = c(1,1,1,1,1,1,1,1), company = c(1,1,1,2,2,2,1,1),
               year = c(1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997))

你看到 person == 1 從 1990 年到 1992 年在公司 1 工作,然后從 1993 年到 1995 年切換到公司 2。然后他從 1996 年到 1997 年回到公司 1。

我想過使用

min <- data[data[, .I[year == min(year)], by=.(person, company)]$V1]
setnames(min, "year", "start")

max <- data[data[, .I[year == max(year)], by=.(person, company)]$V1]
setnames(max, "year", "end")

duration <- merge(min, max, all = T)

你得到:

person company start  end
     1       1  1990 1997
     1       2  1993 1995

但我想要的是:

person company start  end
     1       1  1990 1992
     1       2  1993 1995
     1       1  1996 1997

知道如何獲得嗎?

謝謝。

我們可以使用rleid作為分組變量

library(data.table)
data[, .(start =  min(year), end = max(year)),
    .(person, grp = rleid(company), company)][, grp := NULL][]

-輸出

   person company start  end
1:      1       1  1990 1992
2:      1       2  1993 1995
3:      1       1  1996 1997

或者也可以使用collapse

library(collapse)
data[, grp := rleid(company)]
collap(data,  ~ person + company + grp, list(fmin, fmax))
   person company fmin.year fmax.year grp
1:      1       1      1990      1992   1
2:      1       1      1996      1997   3
3:      1       2      1993      1995   2

可能有更好的方法來做到這一點,但它是這樣的:

library(data.table)
data = data.table(person = c(1,1,1,1,1,1,1,1), company = c(1,1,1,2,2,2,1,1),
                   year = c(1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997))

data[, c('start', 'end', 'group') := 0]
group_count = 0

for (i in seq_len(nrow(data))) {
  if (i == 1) {
    next
    } else if (data[i, company] != data[i-1, company]) {
    group_count = group_count + 1
    data[i, group := group_count]
    } else {
    data[i, group := group_count]
    }
}

data[, c('start', 'end') := .(min(year), max(year)), by = group]

data = unique(data[, .(person, company, start, end)])

> data
   person company start  end
1:      1       1  1990 1992
2:      1       2  1993 1995
3:      1       1  1996 1997

采用@akrun 的回答

如果你的數據集很大

data[, grp := rleid(company), by=.(person)]

min <- data[data[, .I[year == min(year)], by=.(person, company, grp)]$V1]
setnames(min, "year", "start")

max <- data[data[, .I[year == max(year)], by=.(person, company, grp)]$V1]
setnames(max, "year", "end")

duration <- merge(min, max, all = T)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM