由于我对R中使用循环和相关的循环等效函数(例如purrr
和apply()
相关函数的经验不足,所以我认为我的问题很容易解决。但是,花一些时间时间没有任何确定的结果,向社区询问似乎更为合理。
为了理解问题,请想象使用mtcars
包中的数据。我想创建一个基于某个值的变量,例如wt
(重量)。因此,数据帧按降序排列如下:
library(tidyverse)
library(mtcars)
df <- mtcars %>%
arrange(desc(wt))
在下面,我想创建一个基于wt
的最大值的变量。我想用滞后值除以某个除数(2)来划分每个值,这个除数仍然很出色。但是,假设不计算这些值,代码将如下所示:
df <- mtcars %>%
arrange(desc(wt)) %>%
mutate(wt_2 = if_else(wt == max(wt),
wt,
lag(wt_2) / 2))
我知道mutate
不能正常工作,因为需要为else参数创建wt_2
,但是如果有人在新的代码部分中指定,它将起作用。这意味着:
df <- mtcars %>%
arrange(desc(wt)) %>%
mutate(wt_2 = if_else(wt == max(wt),
wt,
0)) %>%
mutate(wt_2 = if_else(wt_2 != max(wt),
lag(wt_2) / 2,
wt_2))
但是,只有第二个观察值被分配了计算值。问题在于应该预先计算应分配给变量的值。因此,我认为某种循环机制是必要的。 使用上述代码后,只有第二个观察值被分配了计算值:
glimpse(df$wt_2)
num [1:32] 5.425 2.71 1.36 0.68 0.34 ...
第三个值应为2.71 / 2 = 1.355
。第四个值1.355 / 2
等等……
新变量wt_2
应该不引用wt
,但最大值(5.42或5.425不四舍五入)除外。应该为每个观察值分配同一变量的前一个观察值的滞后值(使用lag
的逻辑)除以2(或另一个值,但在本示例中,我决定选择2作为除数)。
但是,问题在于,由于只有第一个观察值或第一和第二个观察值被分配了值,因此无法使用该代码。可以手动计算每个值,但也可以使用循环相关函数更轻松地获得计算出的值。
答案 0 :(得分:1)
由于R是向量化语言,因此通常不需要循环。
在这里,您希望每行的最大值除以2,这相当于将行数的幂除以1除以2。
因此,此代码应提供预期的输出:
df=mtcars %>%
select(wt) %>%
arrange(desc(wt)) %>%
mutate(wt_2 = max(wt) / 2^(row_number()-1))) %>%
round(2)
预期输出:
glimpse(df$wt_2)
#num [1:32] 5.42 2.71 1.36 0.68 0.34 0.17 0.08 0.04 0.02 0.01 ...