根据特定行值将列添加到数据框 (2)
Add column to dataframe depending on specific row values (2)
我必须调整一个代码,它可以在不同的 data.frame 但条件相似的情况下完美运行。
这是我的例子 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 9527 0
88662 9528 0
1845 9528 0
8872 2287 0
49002 1914 0
1664 1915 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 9527 0 1
88662 9528 0 1
1845 9528 0 1
8872 2287 0 3
49002 1914 0 2
1664 1915 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 9527 0 1
88662 9528 0 1
1845 9528 0 1
21009 1913 3 2
24005 1913 3 2
25009 1913 3 2
49002 1914 0 2
1664 1915 0 2
22317 2286 2 3
37612 2286 2 3
8872 2287 0 3
25009 14329 1 4
我的真实 data.frame 比示例更复杂(即 Count
列中的更多列和更多值)。
@mrbrick 在我之前的问题 () 中建议我的代码如下:
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)))
但它仅适用于第 x 天、第 x -1 天和第 x -2 天。
任何建议都会很有帮助。
假设不同顺序组中的 Day
值是这样的,即删除 Day
的最后两位数字标识每个组将剩下的转换为以序列号作为标签的因子。没有使用包。
g <- df$Day %/% 100
u <- unique(g)
transform(df, new_col = factor(g, levels = u, labels = seq_along(u)))
给予:
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 21009 1913 3 2
6 24005 1913 3 2
7 25009 1913 3 2
8 22317 2286 2 3
9 37612 2286 2 3
10 25009 14329 1 4
11 48007 9527 0 1
12 88662 9528 0 1
13 1845 9528 0 1
14 8872 2287 0 3
15 49002 1914 0 2
16 1664 1915 0 2
另一种可能性是将 g <- ...
行替换为以下内容之一:
(a) 已知组数 使用 kmeans
和适当的簇数:
g <- kmeans(df$Day, 4)$cluster
(b) 手动设置 或手动设置中心并使用它来启动 kmeans
:
centers <- c(1913, 2286, 9526, 14329) + 1
g <- kmeans(df$day, centers)$cluster
(c) 检查 x-1 和 x-2 或像这样导出 centers
。如果一天 x
没有 x-1
或 x-2
,那么 x
必须是序列中的第一个,所以我们挑选出这样的值并加 1 以获得中心。与 (a) 要求我们知道簇的数量和 (b) 要求我们知道实际序列不同,这个不需要知道这些序列。
centers <- with(df, unique(Day[ ! ((Day-1) %in% Day) & ! ((Day-2) %in% Day) ]) + 1)
g <- kmeans(df$Day, centers)$cluster
(d) 最后一点的简化 或者如果我们保证如果 x
是序列中的第一个那么 x, x+1 和 x+2如果没有 x-1
,那么我们可以确定 x
是序列中的第一个,因此我们可以将 (c) 简化为:
# assumes x, x+1, x+2 all appear for each sequence
centers <- with(df, unique(Day[ ! (Day-1) %in% Day ]) + 1)
g <- kmeans(df$Day, centers)$cluster
kmeans
解决方案应该有效,如果这些组足够分离并且根据问题中显示的数据看来它们是有效的。
使用 base R,您可以创建一个 data.frame,其中包含 ID 列、您想要的日期(x
、x+1
、x+2
)以及 new_col
你想要,然后将这个 data.frame 与你原来的合并。
如果您提前知道所有 x
天,那将有效。
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 9527 0
88662 9528 0
1845 9528 0
8872 2287 0
49002 1914 0
1664 1915 0', header = TRUE)
# identify the day you want (x variable in your example)
x <- c(9526, 1913, 2286, 14329)
# create new_col for each x as you wish, and repeat for x + i, then rbind the results data.frame
new_col_df <- do.call(rbind,
lapply(seq(0, 2, by = 1),
function(add) data.frame(x = x + add, new_col = seq_along(x))
)
)
# merge with the original df
output_df <-merge(df, new_col_df, by.x = "Day", by.y = "x")
# ordered output is
output_df[order(output_df$new_col),]
#> Day ID Count new_col
#> 9 9526 33012 4 1
#> 10 9526 35004 4 1
#> 11 9526 37006 4 1
#> 12 9526 37008 4 1
#> 13 9527 48007 0 1
#> 14 9528 88662 0 1
#> 15 9528 1845 0 1
#> 1 1913 21009 3 2
#> 2 1913 24005 3 2
#> 3 1913 25009 3 2
#> 4 1914 49002 0 2
#> 5 1915 1664 0 2
#> 6 2286 22317 2 3
#> 7 2286 37612 2 3
#> 8 2287 8872 0 3
#> 16 14329 25009 1 4
我必须调整一个代码,它可以在不同的 data.frame 但条件相似的情况下完美运行。
这是我的例子 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 9527 0
88662 9528 0
1845 9528 0
8872 2287 0
49002 1914 0
1664 1915 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 9527 0 1
88662 9528 0 1
1845 9528 0 1
8872 2287 0 3
49002 1914 0 2
1664 1915 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 9527 0 1
88662 9528 0 1
1845 9528 0 1
21009 1913 3 2
24005 1913 3 2
25009 1913 3 2
49002 1914 0 2
1664 1915 0 2
22317 2286 2 3
37612 2286 2 3
8872 2287 0 3
25009 14329 1 4
我的真实 data.frame 比示例更复杂(即 Count
列中的更多列和更多值)。
@mrbrick 在我之前的问题 (
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)))
但它仅适用于第 x 天、第 x -1 天和第 x -2 天。
任何建议都会很有帮助。
假设不同顺序组中的 Day
值是这样的,即删除 Day
的最后两位数字标识每个组将剩下的转换为以序列号作为标签的因子。没有使用包。
g <- df$Day %/% 100
u <- unique(g)
transform(df, new_col = factor(g, levels = u, labels = seq_along(u)))
给予:
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 21009 1913 3 2
6 24005 1913 3 2
7 25009 1913 3 2
8 22317 2286 2 3
9 37612 2286 2 3
10 25009 14329 1 4
11 48007 9527 0 1
12 88662 9528 0 1
13 1845 9528 0 1
14 8872 2287 0 3
15 49002 1914 0 2
16 1664 1915 0 2
另一种可能性是将 g <- ...
行替换为以下内容之一:
(a) 已知组数 使用 kmeans
和适当的簇数:
g <- kmeans(df$Day, 4)$cluster
(b) 手动设置 或手动设置中心并使用它来启动 kmeans
:
centers <- c(1913, 2286, 9526, 14329) + 1
g <- kmeans(df$day, centers)$cluster
(c) 检查 x-1 和 x-2 或像这样导出 centers
。如果一天 x
没有 x-1
或 x-2
,那么 x
必须是序列中的第一个,所以我们挑选出这样的值并加 1 以获得中心。与 (a) 要求我们知道簇的数量和 (b) 要求我们知道实际序列不同,这个不需要知道这些序列。
centers <- with(df, unique(Day[ ! ((Day-1) %in% Day) & ! ((Day-2) %in% Day) ]) + 1)
g <- kmeans(df$Day, centers)$cluster
(d) 最后一点的简化 或者如果我们保证如果 x
是序列中的第一个那么 x, x+1 和 x+2如果没有 x-1
,那么我们可以确定 x
是序列中的第一个,因此我们可以将 (c) 简化为:
# assumes x, x+1, x+2 all appear for each sequence
centers <- with(df, unique(Day[ ! (Day-1) %in% Day ]) + 1)
g <- kmeans(df$Day, centers)$cluster
kmeans
解决方案应该有效,如果这些组足够分离并且根据问题中显示的数据看来它们是有效的。
使用 base R,您可以创建一个 data.frame,其中包含 ID 列、您想要的日期(x
、x+1
、x+2
)以及 new_col
你想要,然后将这个 data.frame 与你原来的合并。
如果您提前知道所有 x
天,那将有效。
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 9527 0
88662 9528 0
1845 9528 0
8872 2287 0
49002 1914 0
1664 1915 0', header = TRUE)
# identify the day you want (x variable in your example)
x <- c(9526, 1913, 2286, 14329)
# create new_col for each x as you wish, and repeat for x + i, then rbind the results data.frame
new_col_df <- do.call(rbind,
lapply(seq(0, 2, by = 1),
function(add) data.frame(x = x + add, new_col = seq_along(x))
)
)
# merge with the original df
output_df <-merge(df, new_col_df, by.x = "Day", by.y = "x")
# ordered output is
output_df[order(output_df$new_col),]
#> Day ID Count new_col
#> 9 9526 33012 4 1
#> 10 9526 35004 4 1
#> 11 9526 37006 4 1
#> 12 9526 37008 4 1
#> 13 9527 48007 0 1
#> 14 9528 88662 0 1
#> 15 9528 1845 0 1
#> 1 1913 21009 3 2
#> 2 1913 24005 3 2
#> 3 1913 25009 3 2
#> 4 1914 49002 0 2
#> 5 1915 1664 0 2
#> 6 2286 22317 2 3
#> 7 2286 37612 2 3
#> 8 2287 8872 0 3
#> 16 14329 25009 1 4