基于多列的 R 条件计数器

标签 r loops dataframe increment tidyverse

我有一个数据框,其中包含受试者(subid)的多个响应,这些响应位于标记为试验的列中。试验进行计数,然后在一个受试者内重新开始。

这是一个示例数据框:

subid <- rep(1:2, c(10,10))
trial <- rep(1:5, 4)
response <- rnorm(20, 10, 3)

df <- as.data.frame(cbind(subid,trial, response))
df

   subid trial  response
1      1     1  3.591832   
2      1     2  8.980606     
3      1     3 12.943185     
4      1     4  9.149388     
5      1     5 10.192392     
6      1     1 15.998124     
7      1     2 13.288248     

我想要一个列,每次试验在一个受试者 ID (subid) 内开始时都会递增:

df$block <- c(rep(1:2, c(5,5)),rep(1:2, c(5,5)))
df
     subid trial response block
1      1     1  3.591832     1
2      1     2  8.980606     1
3      1     3 12.943185     1
4      1     4  9.149388     1
5      1     5 10.192392     1
6      1     1 15.998124     2
7      1     2 13.288248     2

无法预测试验将在哪里重新开始。到目前为止,我的解决方案很困惑,并且使用了 for 循环。

解决方案:

block <- 0
blocklist <- 0

for (i in seq_along(df$trial)){
   if (df$trial[i]==1){
     block = block + 1}else
   if (df$trial!=1){
     block = block}
  blocklist<- c(blocklist, block)
}

blocklist <- blocklist[-1]
df$block <- blocklist

此解决方案不会从新的 subid 开始。在我开始之前,我尝试在管道中使用 Wickham 的 tidyverse 和 mutate() 和 ifelse() 。如果有人知道用那个包来完成这个任务的方法,我将不胜感激。但是,我将使用任何包中的解决方案。我已经搜索了大约一天,不认为这与 this 等其他问题是重复的问题。 .

最佳答案

我们可以使用base R中的ave来做到这一点

df$block <- with(df, ave(trial, subid, FUN = function(x) cumsum(x==1)))

或者使用dplyr

library(dplyr)
df %>%
   group_by(subid) %>%
   mutate(block = cumsum(trial==1))

关于基于多列的 R 条件计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43020317/

相关文章:

r - 取消列出 R 中的对象,但用 NAs 替换 numeric(0)

python - 如何避免在内部 Python 样式循环中调用相同的函数

python - 从python中的字符串中获取两个字符

r - 如何修改选定行的n个后续值

python - Pandas DataFrame.merge 内存错误

r - For 循环遍历 R 的 gsub 中使用的项目列表

r - 如何提取具有正值和负值的相同行

r - 计算包含 xy 坐标列表的数据框中所有点之间距离的方法

r - 创建对称矩阵的最有效方法

dataframe - 如何使用 Julia、Pluto.jl 和 PlutoUI.jl 的 FilePicker 元素读取上传的 CSV 文件