Select 按因素水平排列

Select row by level of a factor

我有一个数据框 df2,其中包含按 ID factor 分组的观察结果,我想对其进行子集化。我使用了另一个函数来确定我想要 select 每个因子组 中的哪些行 。如下所示 df:

df <- data.frame(ID = c("A","B","C"),
                 pos = c(1,3,2))
df2 <- data.frame(ID = c(rep("A",5), rep("B",5), rep("C",5)),
                  obs = c(1:15))

df中,pos对应于我想要select在ID中提到的因子级别内的行的索引,而不是在整个数据框中df2。我正在寻找一种方法 select 每个 ID 的行根据正确的索引(因此它们的行号在 df2 的每个因素的水平内).

所以,在这个例子中,我想 select df2 中的第一个值 ID == 'A'df2 中的第三个值 ID == 'B' df2ID == 'C'.

中的第二个值

这会给我:

df3 <- data.frame(ID = c("A", "B", "C"),
                  obs = c(1, 8, 12))

dplyr

library(dplyr)

merge(df,df2) %>% 
  group_by(ID) %>% 
  filter(row_number() == pos) %>%
  select(-pos)

#   ID obs
# 1  A   1
# 2  B   8
# 3  C  12

基础 R

df2m <- merge(df,df2)
do.call(rbind, 
  by(df2m, df2m$ID, function(SD) SD[SD$pos[1], setdiff(names(SD),"pos")]) 
)

by将合并后的数据帧df2m拆分为df2m$ID,并对每一部分进行操作;它 returns 会生成一个列表,因此最后它们必须 rbind 在一起。数据的每个子集(与 ID 的每个值相关联)由 pos 过滤并使用正常 data.frame 语法取消选择 "pos" 列。

data.table @DavidArenburg 在评论中建议

library(data.table)

setkey(setDT(df2),"ID")[df][, 
  .SD[pos[1L], !"pos", with=FALSE]
, by = ID]

第一部分——setkey(setDT(df2),"ID")[df]——是合并。之后,将得到的table拆分为by = ID,并对每个数据子集.SD进行操作。 pos[1L] 以正常方式进行子集化,而 !"pos", with=FALSE 对应于删除 pos 列。

请参阅@eddi 的回答以获得更好的 data.table 方法。

这是基本的 R 解决方案:

df2$pos <- ave(df2$obs, df2$ID, FUN=seq_along)
merge(df, df2)
  ID pos obs
1  A   1   1
2  B   3   8
3  C   2  12

如果df2ID排序,你可以只对第一行做df2$pos <- sequence(table(df2$ID))

使用 data.table 版本 1.9.5+:

setDT(df2)[df, .SD[pos], by = .EACHI, on = 'ID']

合并 ID 列,然后为 df 的每一行选择 pos 行。