我有一个数据框,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解决方案:
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
如果df2
按ID
排序,你可以为第一行做df2$pos <- sequence(table(df2$ID))
。
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
ed。数据的每个子集(与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的答案。
使用data.table
版本1.9.5+:
setDT(df2)[df, .SD[pos], by = .EACHI, on = 'ID']
它合并在ID
列上,然后为pos
的每一行选择df
行。