根据特定行值将列添加到数据框
Add column to dataframe depending on specific row values
我正在尝试解决对我来说几天以来一直存在的问题。
这是我的 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) 和天 (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
我的真实 data.frame 比示例更复杂(即 Count
列中有更多列和更多值,因此如果我更新问题请耐心等待。
任何建议都会很有帮助。
我不确定我是否完全理解您的问题,但您似乎可以使用 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)))
这是一个使用 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
一种更具可扩展性的方法是使用 data.table
包中的 foverlaps
,我们准备查找 table 然后与原始 table 和使用 within
键入 join 以确保日期在查找 table 中指定的范围内,以便更好地解释 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
我正在尝试解决对我来说几天以来一直存在的问题。
这是我的 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) 和天 (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
我的真实 data.frame 比示例更复杂(即 Count
列中有更多列和更多值,因此如果我更新问题请耐心等待。
任何建议都会很有帮助。
我不确定我是否完全理解您的问题,但您似乎可以使用 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)))
这是一个使用 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
一种更具可扩展性的方法是使用 data.table
包中的 foverlaps
,我们准备查找 table 然后与原始 table 和使用 within
键入 join 以确保日期在查找 table 中指定的范围内,以便更好地解释 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