我试图解决一些问题,这对我来说是一个问题,因为几天。
这是我的data.frame的一个例子,我希望它能与我的真实一起工作。
df <- read.table(text = 'ID Day Count
33012 9526 4
35004 9526 4
37006 9526 4
37008 9526 4
21009 1913 3
24005 1913 3
25009 1913 3
22317 2286 2
37612 2286 2
25009 14329 1
48007 9525 0
88662 9524 0
1845 9524 0
8872 2285 0
49002 1912 0
1664 1911 0', header = TRUE)
我需要在我的data.frame中添加一个新列(new_col
),其中包含1到4的值。这些new_col
值必须包含每一天,每天(x)天( x -1)和day(x -2),其中x = 9526,1913,2286,14329(列Day
)。
我的输出应该如下:
ID Day Count new_col
33012 9526 4 1
35004 9526 4 1
37006 9526 4 1
37008 9526 4 1
21009 1913 3 2
24005 1913 3 2
25009 1913 3 2
22317 2286 2 3
37612 2286 2 3
25009 14329 1 4
48007 9525 0 1
88662 9524 0 1
1845 9524 0 1
8872 2285 0 3
49002 1912 0 2
1664 1911 0 2
new_col
订购的data.frame将是:
ID Day Count new_col
33012 9526 4 1
35004 9526 4 1
37006 9526 4 1
37008 9526 4 1
48007 9525 0 1
88662 9524 0 1
1845 9524 0 1
21009 1913 3 2
24005 1913 3 2
25009 1913 3 2
49002 1912 0 2
1664 1911 0 2
22317 2286 2 3
37612 2286 2 3
8872 2285 0 3
25009 14329 1 4
我的真实数据框架比示例更复杂(即Count
列中的列数更多,值更多,因此如果我要更新问题,请耐心等待。
任何建议都会非常有用。
答案 0 :(得分:1)
我不确定我是否完全理解您的问题,但似乎您可以使用cut()
来实现此目标,如下所示:
x <- c(1913, 2286, 9526, 14329)
df$new_col <- cut(df$Day, c(-Inf, x, Inf))
df$new_col <- as.numeric(factor(df$new_col, levels=unique(df$new_col)))
答案 1 :(得分:0)
以下是使用dplyr
软件包的不可扩展且易于理解的解决方案,我们可以使用case_when
根据条件重新编制日期:
library(dplyr)
df %>% mutate(new_col = case_when(abs(df$Day - 9526) <= 2 ~ 1,
abs(df$Day - 1913) <= 2 ~ 2,
abs(df$Day - 2286)<= 2 ~ 3,
abs(df$Day - 14329) <= 2 ~ 4)) %>%
arrange(new_col)
# ID Day Count new_col
# 1 33012 9526 4 1
# 2 35004 9526 4 1
# 3 37006 9526 4 1
# 4 37008 9526 4 1
# 5 48007 9525 0 1
# 6 88662 9524 0 1
# 7 1845 9524 0 1
# 8 21009 1913 3 2
# 9 24005 1913 3 2
# 10 25009 1913 3 2
# 11 49002 1912 0 2
# 12 1664 1911 0 2
# 13 22317 2286 2 3
# 14 37612 2286 2 3
# 15 8872 2285 0 3
# 16 25009 14329 1 4
更可扩展的方法是使用foverlaps
包中的data.table
,我们准备一个查找表,然后与原始表联接,并使用within
类型连接来制作确保日期在查找表中指定的范围内,以便更好地解释foverlaps
library(data.table)
# prepare the look up table
x <- c(9526, 1913, 2286, 14329)
dt1 <- data.table(start = x - 2, end = x, new_col = 1:4)
setkey(dt1)
dt1
# start end new_col
# 1: 1911 1913 2
# 2: 2284 2286 3
# 3: 9524 9526 1
# 4: 14327 14329 4
# prepare the original table
dt = copy(setDT(df))
dt[, Day2 := Day]
# do a foverlaps
foverlaps(dt, dt1, by.x = c("Day", "Day2"), by.y = c("start", "end"), type = "within", mult = "all", nomatch = 0L)[, .(ID, Day, Count, new_col)][order(new_col)]
# ID Day Count new_col
# 1 33012 9526 4 1
# 2 35004 9526 4 1
# 3 37006 9526 4 1
# 4 37008 9526 4 1
# 5 48007 9525 0 1
# 6 88662 9524 0 1
# 7 1845 9524 0 1
# 8 21009 1913 3 2
# 9 24005 1913 3 2
# 10 25009 1913 3 2
# 11 49002 1912 0 2
# 12 1664 1911 0 2
# 13 22317 2286 2 3
# 14 37612 2286 2 3
# 15 8872 2285 0 3
# 16 25009 14329 1 4