使用 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))
但是,我仍然不确定如何 link 这两个数据帧来提取我需要的内容。
我们获取 'v1'、'v2' 的行索引,其中值在 'df2' 中最高的列按 'MyID' 分组,然后与第一个进行连接dataset by 'MyID' and summarise
'v1', 'v2' columns based on the index grouping by '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
我们可以group_by
MyID
得到每列中最大值的索引并存储在df3
.
library(dplyr)
df2 %>%
group_by(MyID) %>%
summarise(across(.fns = which.max)) -> df3
我们按行拆分 df3
,按行拆分 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
我正在处理一个非常大的数据集。考虑以下示例进行说明:
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))
但是,我仍然不确定如何 link 这两个数据帧来提取我需要的内容。
我们获取 'v1'、'v2' 的行索引,其中值在 'df2' 中最高的列按 'MyID' 分组,然后与第一个进行连接dataset by 'MyID' and summarise
'v1', 'v2' columns based on the index grouping by '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
我们可以group_by
MyID
得到每列中最大值的索引并存储在df3
.
library(dplyr)
df2 %>%
group_by(MyID) %>%
summarise(across(.fns = which.max)) -> df3
我们按行拆分 df3
,按行拆分 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