计算 R 中可变列范围内的行最小/最大值

问题描述 投票:0回答:1

对于 R 中的数据分析,我尝试计算变量 A1,它是一系列值中的最小值。棘手的是,范围的起始位置取决于前一个变量 D1 的索引(这是前面列的最大值)。

示例:

df <- data.frame(ID = 1:5, V1 = c(2, 5, 2, 8, 3), V2 = c(3, 4, 4, 7, 1), V3 = c(7, 2, 8, 1, 5), V4 = c( 1, 2,3, 4, 6), V5 = c(3, 2, 5, 2, 8))
df

D1_range <- 2:3
df$D1 <- apply(df[,D1_range],1, max)
df$indexD1 <- apply(df[,D1_range], 1,which.max)
df

D1 是 V1:V2 的最大值。 A1 的范围从索引 D1 + 1 开始。例如,对于 ID=5,这将从 V2 开始,而对于 ID=1,这将从 V3 开始。

现在我尝试用多种不同的方式来表示 A1 的范围。例如通过计算范围:

df$A1_start <- df$indexD1+1
df$A1_end <- 6
df
df$A1 <- df %>% rowwise() %>% do.call(pmin, df[,df$A1_start:df$A1_end])

或者使用 apply

df$A1 <- apply(df[,df$A1_start:6], min)
df
df$A1 <- df %>% rowwise() %>% apply(df[,df$A1_start:6], min)
df

并进行变异:

df <- df %>% rowwise() %>% mutate(A1 = min(c_across(A1_range)))
df

我还尝试将范围写为字符串:


df$A1_range <- "{df$A1_start}:{df$A1_end}"

但这只会创建一个非常奇怪的变量,其中包含文本“{df$A1_start}:{df$A1_end}”

我还发现了另一篇使用子集的帖子,并在管道中进行了尝试,但如果这样做,我会收到错误:

df <- df %>% rowwise() %>% mutate(A1test = min(subset(., select = A1_startname:A1_endname)))

(注意:在我的真实数据中,我计算了 A1_startname 和 A1_endname,它们也是字符串而不是索引的列名)

问题是:即使我可以获得计算值 A1 的代码,它也会将列表中第一个(ID = 1)的 A1_start 值作为每行范围的开始。然而,在某些情况下,这是不正确的。例如ID=5,D1是V1中的值,所以A1的范围应该从V2开始,但现在是从V3开始。

有人可以帮我找到一种在函数内使用变量范围来找到最小值的方法吗? 谢谢!

编辑以包括所需的输出:

如果该函数有效,它应该看起来像这样:

df <- data.frame(ID = 1:5, V1 = c(2, 5, 2, 8, 3), V2 = c(3, 4, 4, 7, 1), V3 = c(7, 2, 8, 1, 5), V4 = c( 1, 2,3, 4, 6), V5 = c(3, 2, 5, 2, 8), D1 = c(3, 5,4,8,3), D1index = c(1,1,2,2,1), A1start= c(3,2,3,3,2), A1 = c(1, 2, 3, 1,1))
df

如果 A1 的范围不根据行而变化(因此,如果它采用值 A1start[1] 作为数据框中 /all/ 行的范围的开始),那么您将在 ID 中得到不正确的 A1 =5,因为在范围 3:5 中最小值将为 5,但该行中 A1 的实际正确值应为 1(因为该行的范围从 V2 开始)。

希望这有帮助。 :)

注意:我只是创建了一个非常简单的数据框来说明,但实数不是整数,而是有 6 位数字/小数。因此,对于真实数据,我认为我们可以安全地假设任何地方都不会有重复值。

注2: 我将 D1index 和 A1start 添加到数据帧作为中间步骤。不过,如果 A1 可以在没有这两个变量的情况下计算出来,那也可以。 所以期望的输出也可能只是:

df <- data.frame(ID = 1:5, V1 = c(2, 5, 2, 8, 3), V2 = c(3, 4, 4, 7, 1), V3 = c(7, 2, 8, 1, 5), V4 = c( 1, 2,3, 4, 6), V5 = c(3, 2, 5, 2, 8), D1 = c(3, 5,4,8,3), A1 = c(1, 2, 3, 1,1))
df

r range min rowwise
1个回答
0
投票

因此,经过一些反馈后,我通过创建一个按行遍历数据的 for 循环找到了解决方案。像这样:

df <- df %>% mutate(A1_start = indexD1 +1, A1_end = 5)

df$A1 <- NA
for (i in 1:nrow(df)){
  A1_range <- df$A1_start[i]:5
  df$A1 <- apply(df[,A1_range], 1, min)

不过,我很想知道是否还有其他解决方案!

© www.soinside.com 2019 - 2024. All rights reserved.