ail*_*ail 5 r append data-manipulation
我有带有分组变量“ID”和一些值的数据:
ID, Value
1, 1
1, 2
1, 3
1, 4
2, 5
2, 6
2, 7
2, 8
Run Code Online (Sandbox Code Playgroud)
在每个组中,我想在最后一行之后附加第一行。期望的结果:
ID, Value
1, 1
1, 2
1, 3
1, 4
1, 1 # First row of ID 1 inserted as last row in the group
2, 5
2, 6
2, 7
2, 8
2, 5 # First row of ID 2 inserted as last row in the group
Run Code Online (Sandbox Code Playgroud)
我有 5000 行这个。
在 中tidyverse,您可以使用add_rowwith do(现已弃用)或group_modify(实验性):
dat |>\n group_by(ID) |>\n do(add_row(., ID = unique(.$ID), Value = first(.$Value))) |>\n ungroup()\nRun Code Online (Sandbox Code Playgroud)\ndat |>\n group_by(ID) |>\n group_modify(~ add_row(., Value = first(.$Value))) |>\n ungroup()\nRun Code Online (Sandbox Code Playgroud)\n或者bind_rows与summarize(我的@Gregor Thomas的变体,谢谢):
dat |> \n group_by(ID) |>\n summarize(bind_rows(cur_data(), head(cur_data(), 1))) |>\n ungroup()\nRun Code Online (Sandbox Code Playgroud)\n或者通过使用 @Henrik 的相同逻辑,使用bind_rows、filter和arrange:
dat |> \n group_by(ID) |>\n summarize(bind_rows(cur_data(), head(cur_data(), 1))) |>\n ungroup()\nRun Code Online (Sandbox Code Playgroud)\n输出:
\ndat |>\n bind_rows(dat |> filter(!duplicated(ID))) |>\n arrange(ID)\nRun Code Online (Sandbox Code Playgroud)\n感谢@SamR 提供的数据。
\n这是一个基本的 R 方法:
do.call(rbind,
lapply(split(dat, dat$ID), \(id_df) rbind(id_df, id_df[1,]))
)
# ID Value
# 1.1 1 1
# 1.2 1 2
# 1.3 1 3
# 1.4 1 4
# 1.5 1 1
# 2.5 2 5
# 2.6 2 6
# 2.7 2 7
# 2.8 2 8
# 2.51 2 5
Run Code Online (Sandbox Code Playgroud)
它确实给了你稍微奇怪的行名称 - 如果你关心它,你可以将它包装在(或通过管道传输到)中tibble::as_tibble(),这会完全删除行名称。
或者您可以这样做data.table::rbindlist(lapply(split(dat, dat$ID), \(id_df) rbind(id_df, id_df[1,]))),因为data.table也不使用行名称。
数据
dat <- read.csv(text = "ID, Value
1, 1
1, 2
1, 3
1, 4
2, 5
2, 6
2, 7
2, 8", h=T)
Run Code Online (Sandbox Code Playgroud)