在R中计算跨变量范围的行最小值/最大值。

3
为了在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的范围从indexD1 + 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

并且使用mutate:
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}"。
我还发现另一篇帖子中使用了subset,并尝试在管道中使用它,但如果我这样做会出错。
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]的值作为数据框中所有行的范围的起始值),那么在ID=5中,你将得到一个错误的A1值,因为在范围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


嗨罗莎!欢迎来到Stack Overflow!请展示给我们你想要的输出结果。 - undefined
嗨马克, 感谢你在StackOverflow上的帮助。我在消息末尾作为编辑添加了一个包含所需输出的数据框。 - undefined
对我来说,"A1"的范围从"indexD1 + 1"开始。例如,对于ID=5,这将从V2开始,而对于ID=1,这将从V3开始。这让我感到困惑。因为当ID等于5时,"indexD1"的值为2,所以"2+1"等于3,为什么会翻译成"V2"呢? - undefined
是的,你说得对。当我编辑时,我改变了数据框中的一些值,以更好地说明问题。如果你再次运行代码,那么indexD1现在应该是1,对于ID=5,A1的起始位置现在应该是2。对于造成的困惑,我表示抱歉! - undefined
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)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接