查找值为零的行并在其前后添加行数
Find row of value zero and add a row count before and after it
基于以下数据:
library(tidyverse)
limit <- c(7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5)
group <- c("a", "a", "a", "a", "a", "a", "a", "a", "a","b", "b", "b", "b", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c", "c", "c", "c", "c")
df <- data.frame(limit, group)
df
我想创建一个新列 (NewCol),如下所示:
如果有一行 limit = Id,那在 NewCol 上应该是 0。但是我希望 0 之前的所有行都以相反的顺序返回到组的第一行,并且 0 之后的所有行都被计算到组的末尾。
例如,在那种情况下,对于 "a" 组,它应该看起来像
-6, -5, -4, -3, -2, -1, 0, 1, 2 其中 -6 是该组的第一行,2 是第 9 行。
这是我已经尝试过但仍然没有得到我需要的东西
df %>% group_by(group) %>% mutate(Id = seq(1:length(limit))) %>%
mutate(NewCol = ifelse(limit == Id, 0, NA)) %>%
mutate(nn=ifelse(is.na(NewCol),
zoo::na.locf(NewCol) + cumsum(is.na(NewCol))*1,
NewCol))
谢谢
只是row_number()
和
分组后的'limit'的区别
library(dplyr)
df %>%
group_by(group) %>%
mutate(NewCol = row_number() - limit)
或使用data.table
library(data.table)
setDT(df)[, NewCol := seq_len(.N) - limit]
或 base R
df$NewCol <- with(df, ave(seq_along(limit), group, FUN = seq_along) - limit)
在 Base R 中,我们可以使用 ave
:
df$NewCol <- with(df, ave(limit, group, FUN = seq_along) - limit)
# limit group NewCol
#1 7 a -6
#2 7 a -5
#3 7 a -4
#4 7 a -3
#5 7 a -2
#6 7 a -1
#7 7 a 0
#8 7 a 1
#9 7 a 2
#10 4 b -3
#11 4 b -2
#12 4 b -1
#13 4 b 0
#...
或使用data.table
:
library(data.table)
setDT(df)[, NewCol := seq_along(limit) - limit, group]
#Or
#setDT(df)[, NewCol := seq_len(.N) - limit, group]
基于以下数据:
library(tidyverse)
limit <- c(7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5)
group <- c("a", "a", "a", "a", "a", "a", "a", "a", "a","b", "b", "b", "b", "b", "b", "b", "b", "b", "c", "c", "c", "c", "c", "c", "c", "c", "c")
df <- data.frame(limit, group)
df
我想创建一个新列 (NewCol),如下所示:
如果有一行 limit = Id,那在 NewCol 上应该是 0。但是我希望 0 之前的所有行都以相反的顺序返回到组的第一行,并且 0 之后的所有行都被计算到组的末尾。
例如,在那种情况下,对于 "a" 组,它应该看起来像
-6, -5, -4, -3, -2, -1, 0, 1, 2 其中 -6 是该组的第一行,2 是第 9 行。
这是我已经尝试过但仍然没有得到我需要的东西
df %>% group_by(group) %>% mutate(Id = seq(1:length(limit))) %>%
mutate(NewCol = ifelse(limit == Id, 0, NA)) %>%
mutate(nn=ifelse(is.na(NewCol),
zoo::na.locf(NewCol) + cumsum(is.na(NewCol))*1,
NewCol))
谢谢
只是row_number()
和
library(dplyr)
df %>%
group_by(group) %>%
mutate(NewCol = row_number() - limit)
或使用data.table
library(data.table)
setDT(df)[, NewCol := seq_len(.N) - limit]
或 base R
df$NewCol <- with(df, ave(seq_along(limit), group, FUN = seq_along) - limit)
在 Base R 中,我们可以使用 ave
:
df$NewCol <- with(df, ave(limit, group, FUN = seq_along) - limit)
# limit group NewCol
#1 7 a -6
#2 7 a -5
#3 7 a -4
#4 7 a -3
#5 7 a -2
#6 7 a -1
#7 7 a 0
#8 7 a 1
#9 7 a 2
#10 4 b -3
#11 4 b -2
#12 4 b -1
#13 4 b 0
#...
或使用data.table
:
library(data.table)
setDT(df)[, NewCol := seq_along(limit) - limit, group]
#Or
#setDT(df)[, NewCol := seq_len(.N) - limit, group]