我有下表,其中包含一个具有两个级别DH1和DH2的因子变量“类别”。我也有因子变量“ from”和“ to”的间隔值。
category = c('DH1','DH1','DH1','DH1','DH2','DH2')
from = c(356,366,367,368,401,402)
to = c(366,367,368,369,402,403)
df <- data.frame(category,from, to)
category from to
1 DH1 365 366
2 DH1 366 367
3 DH1 367 368
4 DH1 368 369
5 DH2 401 402
6 DH2 402 403
我需要创建两个看起来像这样的新列,其中DH1更改为DH2后,from1从0开始,to1 = to-from
category from to from1 to1
1 DH1 365 366 0 1
2 DH1 366 367 1 2
3 DH1 367 368 2 3
4 DH1 368 369 3 4
5 DH2 401 402 0 1
6 DH2 402 403 1 2
我知道我需要有一个for循环并循环遍历“ category”,然后有一个if语句category[4] != category[5]
并在此基础上计算新列。但是,有没有更简单的方法?
答案 0 :(得分:3)
有一种使用library(dplyr)
的简单方法:
df %>% arrange(category, from)
%>% group_by(category)
%>% mutate(from1 = row_number()-1, to1 = row_number())
它按category
和from
对数据进行排序,并按category
变量分组,以确保from1和to1可以基于每个类别的行号通过使用用于创建新变量的mutate
函数。
答案 1 :(得分:2)
也许您正在寻找
library(dplyr)
df %>%
group_by(category) %>%
mutate(from1 = row_number() - 1,
to1 = cumsum(to - from))
# category from to from1 to1
# <fct> <dbl> <dbl> <dbl> <dbl>
#1 DH1 365 366 0 1
#2 DH1 366 367 1 2
#3 DH1 367 368 2 3
#4 DH1 368 369 3 4
#5 DH2 401 402 0 1
#6 DH2 402 403 1 2
对于每个category
,这将row_number() - 1
的值分配给from1
,并计算to - from
值的累积和。如果未订购category
,并且DH1
可以作为另一个组再次出现,我们可能需要group_by
data.table::rleid(category)
。
答案 2 :(得分:1)
如果您要在每个类别中计算1..n,则可以使用“ dplyr”包:
library(dplyr)
df %>% group_by(category) %>% mutate(to1=1:n(), from1=to1-1)
如果您要比较第i行和第i + 1行中的值,则可以使用{d1yr}中的函数lag
(内置lag
函数仅适用于时间序列):
dplyr::lag(df$category)
[1] <NA> DH1 DH1 DH1 DH1 DH2
Levels: DH1 DH2
(一旦您加载了“ dplyr”软件包,它将替换内置的lag
函数,您无需像我在示例中所写的那样调用它-只是强调我指的功能)