根据特定行值将列添加到数据框

时间:2016-07-29 13:44:41

标签: r dataframe add

我试图解决一些问题,这对我来说是一个问题,因为几天。

这是我的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列中的列数更多,值更多,因此如果我要更新问题,请耐心等待。

任何建议都会非常有用。

2 个答案:

答案 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