逐行选择因子

时间:2015-08-25 17:37:04

标签: r subset r-factor

我有一个数据框df2,其中包含按我要分组的ID factor分组的观察结果。我使用了另一个函数来识别我想要选择的每个因子组中的行。这在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对应于我要在ID中提及的因子级别内选择的行的索引,而不是整个数据框df2。我正在寻找一种方法来根据正确的索引选择每个ID的行(因此它们的行号在每个因子df2的级别内)。

因此,在此示例中,我想选择df2ID == 'A'的第一个值,df2ID == 'B'的第三个值和df2中的第二个值{1}} ID == 'C'

这会给我:

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

3 个答案:

答案 0 :(得分:11)

<强> 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,并对每个部分进行操作;它会在列表中返回结果,因此它们必须在最后rbind处一起显示。数据的每个子集(与ID的每个值相关联)都按pos进行过滤,并使用常规data.frame语法取消选择"pos"列。

@DavidArenburg在评论

中建议

data.table

library(data.table)

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

第一部分 - setkey(setDT(df2),"ID")[df] - 是合并。之后,生成的表格将被分割by = ID,并且每个数据子集.SD都会被操作。 pos[1L]以正常方式进行子集化,而!"pos", with=FALSE对应于删除pos列。

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

答案 1 :(得分:9)

以下是基础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))做。{/ p>

答案 2 :(得分:7)

使用#include MCU_HEADER_FILE版本1.9.5 +:

data.table

合并到setDT(df2)[df, .SD[pos], by = .EACHI, on = 'ID'] 列,然后为ID的每一行选择pos行。