我有两张桌子:
df_workingFile
group v
1 a 110
2 a 90
3 b 57
4 b 53
df_groupIDs
group
1 a
2 b
我想将df_workingFile的最大值从组标签中提取到df_groupIDs
df_groupIDs
groups max
1 a 110
2 b 57
我有代码可以做到这一点,但是对于大型数据集来说它确实很慢。
data.frame(df_groupIDs, maxValue =
sapply(df_groupIDs$group, function(newCol)
max(subset(df_workingFile, newCol == df_workingFile$group)$v)))
有关如何提高效率的任何建议吗?
答案 0 :(得分:4)
使用data.table,这是一个“更新连接”:
library(data.table)
setDT(df_groupIDs)
setDT(df_workingFile)
df_groupIDs[ , mx := df_workingFile[.(.SD$group), on=.(group), max(v), by=.EACHI]$V1 ]
# group mx
# 1: a 110
# 2: b 57
.SD$group
部分不是惯用语。它应该是.SD
,但有一个open bug preventing that。
工作原理
联接的语法是x[i, on=]
,其中i
用于根据x
中的规则在on=
中查找行。更新的语法是x[, var := expr]
。在这里,它们与x[, var := x2[.SD, on=]]
类似,其中.SD
指的是来自x
的数据子集。我们可以等效地将expr
写为
df_workingFile[df_groupIDs, on=.(group), max(v), by=.EACHI]$V1
请参阅?data.table
中有关by=.EACHI
正在做什么的文档。 V1
只是计算结果的默认名称(在本例中为max(v)
)。
性能
我有代码可以做到这一点,但是对于大型数据集来说它确实很慢。
这种方法应该相当有效,因为(i)它分配给现有的df_groupIDs
表而不是创建一个新表; (ii)它仅计算df_groupIDs
中显示的组的最大值(而不是df_workingFile
中显示的所有组); (iii)优化分组最大值(见?GForce
)。
有关比较时间(更新加入与dplyr,匹配等)的示例,请参阅merge data.frames based on year and fill in missing values。
答案 1 :(得分:1)
您可以先df_workingFile
计算每个ID的最大值。之后,进行left_join
。
library(dplyr)
df_max <- df_workingFile %>%
group_by(group) %>%
summarise(max = max(v))
df_final <- df_groupIDs %>% left_join(df_max, by = "group")
这是R基础方法。
df_max <- aggregate(v ~ group, data = df_workingFile, FUN = max)
df_final <- merge(df_groupIDs, df_max, by = "group", all.x = TRUE)
答案 2 :(得分:1)
这是一个基本R方法,它使用tapply
计算最大值,然后使用transform
将它们添加到第二个data.frame,使用match
查找正确的索引。
# calculate maximum values
vals <- with(df_workingFile, tapply(v, group, max))
# add new variable
transform(df_groupIDs, max=vals[match(group, names(vals))])
group max
a a 110
b b 57
要添加变量,更标准的表示法是
df_groupIDs$max <- vals[match(df_groupIDs$group, names(vals))]