簡體   English   中英

使用Data.Table有條件地選擇組內的行

[英]Conditionally Select Rows within a Group with Data.Table

我正在尋找使用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

對於每個組,我們要使用以下規則選擇一行:

  • 如果年份> 2000,請選擇最小年份超過 2000的行。
  • 如果沒有> 2000年,請選擇年份最大的行。

期望的輸出:

GROUP  YEAR    NAME
3      1985    Anderson
4      2011    Liam
5      2012    George
6      1994    Adams

謝謝! 我一直在努力解決這個問題。

如果你將特殊的.I行計數器子集化, data.table應該簡單得多:

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

所以,我在這里所做的就是為每個by= level的每個計算得到整個data的匹配行索引。 然后使用這些行索引再次對data進行子集化。

你也可以做幾個滾動連接:

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

使用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

編輯:對不起,我的第一個答案沒有考慮最小/最大條件。 希望這可以幫助

暫無
暫無

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

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