繁体   English   中英

使用 R - 根据另一个数据帧的组最大值重塑数据帧

[英]Using R - reshape a dataframe based on group max values of another dataframe

我正在处理一个非常大的数据集。 考虑以下示例进行说明:

df1<-{data.frame(MyID=c(1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5),v1=c(0.1, 0.2, NA, 0.4, 0.2, 0.1, 0.8, 0.3, 0.1, 0.4, 0.3), v2=c(NA, 0.4, 0.2, 0.1, 0.8, 0.3, 0.1, 0.4, 0.3, 0.1, 0.2))}

df2<-{data.frame(MyID=c(1, 2, 3, 1, 2, 3, 1, 2, 3, 4, 5),v1=c(10, 8, 0, 6, 10, 5, 3, 1, 10, 8, 3), v2=c(0, 10, 5, 1, 8, 5,10, 3, 3, 1, 5))}

我想从 df1 中提取信息,但基于 df2 中每个 MyID 的最大值。 最终结果应该是一个数据框:

  • 每个唯一的 MyID 一行
  • 每列将具有 df1 中的值,对应于 df2 的 MyID 组的最大值。

结果应该是

ExpectedResult<-{data.frame(MyID=c(1, 2, 3, 4, 5),v1=c(0.1,0.2,0.1,0.4,0.3), v2=c(0.1,0.4,0.2,0.1,0.2))}

我已经尝试过但只解决了部分问题:

  • 使用组并找到每组的最大值,例如df2Max<- df2 %>% group_by(MyID) %>% slice_max(1,)
  • 使用例如df2.split <- split(df2, list(df2$MyID))拆分数据

但是,我仍然不确定如何链接两个数据框以提取我需要的内容。

我们可以group_by MyID并获取每列中最大值的索引并将其存储在df3

library(dplyr)

df2 %>%
  group_by(MyID) %>%
  summarise(across(.fns = which.max)) -> df3

我们按行拆分df3并按MyID split df1并使用索引提取相关值。

df3[-1] <- t(mapply(function(x, y) x[cbind(y, 1:ncol(x))], 
            split(df1[-1], df1$MyID), asplit(df3[-1], 1)))

#   MyID    v1    v2
#  <dbl> <dbl> <dbl>
#1     1   0.1   0.1
#2     2   0.2   0.4
#3     3   0.1   0.2
#4     4   0.4   0.1
#5     5   0.3   0.2

我们获得“v1”、“v2”、“df2”中值最高的列的行索引,按“MyID”分组,然后通过“MyID”与第一个数据集连接并summarise “v1”、“ v2'列基于'MyID'分组后的索引

library(dplyr)
df2 %>% 
   group_by(MyID) %>% 
   summarise(rnv1 = row_number()[which.max(v1)], 
             rnv2 = row_number()[which.max(v2)], .groups = 'drop' ) %>%  
   right_join(df1, by = 'MyID') %>%
   group_by(MyID) %>% 
   summarise(v1 = v1[first(rnv1)], v2 = v2[first(rnv2)], .groups = 'drop')

-输出

# A tibble: 5 x 3
#   MyID    v1    v2
#  <dbl> <dbl> <dbl>
#1     1   0.1   0.1
#2     2   0.2   0.4
#3     3   0.1   0.2
#4     4   0.4   0.1
#5     5   0.3   0.2

或者另一种选择是与data.table的连接

library(data.table)    
nm1 <- names(df2)[-1]
setDT(df1)[setDT(df2)[, lapply(.SD, which.max), MyID], 
    Map(function(x, y) x[first(y)], .SD, mget(paste0("i.", nm1))), 
    on = .(MyID), by = .EACHI]
#   MyID  v1  v2
#1:    1 0.1 0.1
#2:    2 0.2 0.4
#3:    3 0.1 0.2
#4:    4 0.4 0.1
#5:    5 0.3 0.2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM