根据 R 中另一个 DataFrame 的条件从 DataFrame 中提取值
Extract values from a DataFrame based on condition on another DataFrame in R
我有以下两个示例数据框:
df1 <- data.frame(EVI_GT=c(0.23, 0.54, 0.36, 0.92), EVI_GNT=c(0.33, 0.65, 0.42, 0.73), EVI_GGT=c(0.43, 0.34, 0.22, 0.98))
df2 <- data.frame(T_ET_GT=c(0.56, 0.23, 0.95, 0.82), T_ET_GNT=c(0.10, 0.74, 0.36, 0.35), T_ET_GGT=c(0.52, 0.31, 0.65, 0.58))
我必须从 df2 中提取对应于 df1(每行)的最小值和最大值的值。例如,df1 中第一行的最小(最大值)值为 0.23(0.43),即第 1 列(第 3 列),因此第一行应从 df2 中提取的值为 0.56 和 0.52。第 2 行类似,依此类推。下面是我想要的输出数据框:
df3 <- data.frame(column1=c(0.56, 0.31, 0.65, 0.35), column2=c(0.52, 0.74, 0.36, 0.58))
我们如何使用 df1 上的条件从 df2 获取 df3?
假设您的数据框具有相同的维度,那应该相当容易!
一种非常直观和简单的方法是循环查找 df1
(或 df2
)中的行数,并找到 df1 中每一行的元素最大和最小的列,因此使用该信息对 df2 进行子集化并将该值归因于 df3。
df3 <- data.frame(
min = NA,
max = NA
)
for (i in seq_len(nrow(df1))) {
max_val <- which.max(df1[i, ])
min_val <- which.min(df1[i, ])
df3[i, 1] <- df2[i, min_val]
df3[i, 2] <- df2[i, max_val]
}
一种更“动态”的方法是逐行(通过应用语句)从 df1 中提取“which.max”和“which.min”,从而形成一个列表指标。然后,可以为第一个和第二个条件(最小值和最大值)定义一个行列对矩阵(将其视为坐标!)。
indexes <- apply(df1, MARGIN = 1, function(x) {
return(list(min_idx = which.min(x), max_idx = which.max(x)))
})
indexes <- dplyr::bind_rows(indexes)
indexes$row <- 1:nrow(indexes)
mins_indexes <- as.matrix(dplyr::select(indexes, c("row", "min_idx")))
maxes_indexes <- as.matrix(dplyr::select(indexes, c("row", "max_idx")))
df3 <- data.frame(
min_vals = df2[mins_indexes],
max_vals = df2[maxes_indexes]
)
这个解决方案大致基于这个问题 Selecting specific elements from a matrix all at once!
注意:我已使该过程尽可能直观,您当然可以使用更巧妙的名称并使用更少的代码行。
您可以使用which.min
和which.max
分别获取最小值和最大值的索引。使用 apply
执行按行操作并对 df2
.
中的数据进行子集化
data.frame(column1 = df2[cbind(1:nrow(df1), apply(df1, 1, which.min))],
column2 = df2[cbind(1:nrow(df1), apply(df1, 1, which.max))])
# column1 column2
#1 0.56 0.52
#2 0.31 0.74
#3 0.65 0.36
#4 0.35 0.58
一种使用purrr
的方法
library(dplyr)
library(purrr)
df1 %>%
# list of row for df1
pmap(~c(...)) %>%
map2_dfr(.y = df2 %>% pmap(~c(...)), # map with list of row df2
.f = function(a, b) { # function that take min/max each row of df1 and extract df2
min_index <- which.min(a)
max_index <- which.max(a)
tibble(min = b[min_index], max = b[max_index])
})
# Output
# A tibble: 4 x 2
min max
<dbl> <dbl>
1 0.56 0.52
2 0.31 0.74
3 0.65 0.36
4 0.35 0.580
我有以下两个示例数据框:
df1 <- data.frame(EVI_GT=c(0.23, 0.54, 0.36, 0.92), EVI_GNT=c(0.33, 0.65, 0.42, 0.73), EVI_GGT=c(0.43, 0.34, 0.22, 0.98))
df2 <- data.frame(T_ET_GT=c(0.56, 0.23, 0.95, 0.82), T_ET_GNT=c(0.10, 0.74, 0.36, 0.35), T_ET_GGT=c(0.52, 0.31, 0.65, 0.58))
我必须从 df2 中提取对应于 df1(每行)的最小值和最大值的值。例如,df1 中第一行的最小(最大值)值为 0.23(0.43),即第 1 列(第 3 列),因此第一行应从 df2 中提取的值为 0.56 和 0.52。第 2 行类似,依此类推。下面是我想要的输出数据框:
df3 <- data.frame(column1=c(0.56, 0.31, 0.65, 0.35), column2=c(0.52, 0.74, 0.36, 0.58))
我们如何使用 df1 上的条件从 df2 获取 df3?
假设您的数据框具有相同的维度,那应该相当容易!
一种非常直观和简单的方法是循环查找 df1
(或 df2
)中的行数,并找到 df1 中每一行的元素最大和最小的列,因此使用该信息对 df2 进行子集化并将该值归因于 df3。
df3 <- data.frame(
min = NA,
max = NA
)
for (i in seq_len(nrow(df1))) {
max_val <- which.max(df1[i, ])
min_val <- which.min(df1[i, ])
df3[i, 1] <- df2[i, min_val]
df3[i, 2] <- df2[i, max_val]
}
一种更“动态”的方法是逐行(通过应用语句)从 df1 中提取“which.max”和“which.min”,从而形成一个列表指标。然后,可以为第一个和第二个条件(最小值和最大值)定义一个行列对矩阵(将其视为坐标!)。
indexes <- apply(df1, MARGIN = 1, function(x) {
return(list(min_idx = which.min(x), max_idx = which.max(x)))
})
indexes <- dplyr::bind_rows(indexes)
indexes$row <- 1:nrow(indexes)
mins_indexes <- as.matrix(dplyr::select(indexes, c("row", "min_idx")))
maxes_indexes <- as.matrix(dplyr::select(indexes, c("row", "max_idx")))
df3 <- data.frame(
min_vals = df2[mins_indexes],
max_vals = df2[maxes_indexes]
)
这个解决方案大致基于这个问题 Selecting specific elements from a matrix all at once!
注意:我已使该过程尽可能直观,您当然可以使用更巧妙的名称并使用更少的代码行。
您可以使用which.min
和which.max
分别获取最小值和最大值的索引。使用 apply
执行按行操作并对 df2
.
data.frame(column1 = df2[cbind(1:nrow(df1), apply(df1, 1, which.min))],
column2 = df2[cbind(1:nrow(df1), apply(df1, 1, which.max))])
# column1 column2
#1 0.56 0.52
#2 0.31 0.74
#3 0.65 0.36
#4 0.35 0.58
一种使用purrr
library(dplyr)
library(purrr)
df1 %>%
# list of row for df1
pmap(~c(...)) %>%
map2_dfr(.y = df2 %>% pmap(~c(...)), # map with list of row df2
.f = function(a, b) { # function that take min/max each row of df1 and extract df2
min_index <- which.min(a)
max_index <- which.max(a)
tibble(min = b[min_index], max = b[max_index])
})
# Output
# A tibble: 4 x 2
min max
<dbl> <dbl>
1 0.56 0.52
2 0.31 0.74
3 0.65 0.36
4 0.35 0.580