逐行选择因子

问题描述 投票:10回答:3

我有一个数据框,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的每个因子的水平内)。

所以,在这个例子中,我想用df2选择ID == 'A'中的第一个值,使用df2选择ID == 'B'中的第三个值,使用df2选择ID == 'C'中的第二个值。

这会给我:

df3 <- data.frame(ID = c("A", "B", "C"),
                  obs = c(1, 8, 12))
r subset r-factor
3个回答
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))


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并对每个部分进行操作;它将结果返回到列表中,因此它们必须在最后一起进行rbinded。数据的每个子集(与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列。

有关更好的data.table方法,请参阅@ eddi的答案。


7
投票

使用data.table版本1.9.5+:

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

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

© www.soinside.com 2019 - 2024. All rights reserved.