[英]Merge rows with same pattern name in dataframe R
我正在尝试分析从经验中获得的一些结果。 我有一个大型数据框,格式如下:
Name V1 V2 V3
X1247 1 9 0
X1247.1 1 7 0
X1247.10 2 2 4
X1247.100 8 3 7
X874 3 7 1
X874.1 4 0 1
X66 8 9 1
X66.1 0 1 8
我正在寻找一个数据框,该数据框将合并在“。”之前具有相同名称的行,以便看起来像这样:
Name V1 V2 V3
X1247 12 21 11
X874 7 7 2
X66 8 10 9
怎么办呢? 这可能微不足道,但我更是生物学家,而不是计算机科学家。 谢谢
我们按“名称”(的子str_remove
从stringr
),并使用summarise_all
得到输出
library(tidyverse)
df1 %>%
group_by(Name = str_remove(Name, "\\..*")) %>%
summarise_all(sum)
# A tibble: 3 x 4
# Name V1 V2 V3
# <chr> <int> <int> <int>
#1 X1247 12 21 11
#2 X66 8 10 9
#3 X874 7 7 2
或将base R
与aggregate
和sub
aggregate(.~ Name, transform(df1, Name = sub("\\..*", "", Name)), FUN = sum)
df1 <- structure(list(Name = c("X1247", "X1247.1", "X1247.10", "X1247.100",
"X874", "X874.1", "X66", "X66.1"), V1 = c(1L, 1L, 2L, 8L, 3L,
4L, 8L, 0L), V2 = c(9L, 7L, 2L, 3L, 7L, 0L, 9L, 1L), V3 = c(0L,
0L, 4L, 7L, 1L, 1L, 1L, 8L)), class = "data.frame", row.names = c(NA,
-8L))
data.table解决方案:
data.table::setDT(df1)[,as.list(colSums(.SD)), by=sub("\\.[^.]*", "", Name),][]
# sub V1 V2 V3
#1: X1247 12 21 11
#2: X874 7 7 2
#3: X66 8 10 9
数据:(从akrun借用)
基准:
df1 <- do.call(rbind,rep(list(mtcars),1000))
df1 <- cbind(Name = paste0(rownames(df1),".HAHA"), df1)
f1 <- function(df1) {
setDT(df1)[,as.list(colSums(.SD)), by=sub("\\.[^.]*", "", Name),][]
}
f2 <- function(df1) {
df1 %>%
group_by(Name = str_remove(Name, "\\..*")) %>%
summarise_all(sum)
}
f3 <- function(df1) {
aggregate(.~ Name, transform(df1, Name = sub("\\..*", "", Name)), FUN = sum)
colSums(df1[,-1])
}
microbenchmark::microbenchmark(f1(df1),f2(df1),f3(df1),times=5)
#Unit: milliseconds
# expr min lq mean median uq max neval cld
#f1(df1) 2982.691 3012.7485 3098.9819 3102.7779 3175.1407 3221.5515 5 c
#f2(df1) 292.278 295.4829 299.7829 296.5712 301.3588 313.2236 5 a
#f3(df1) 2244.550 2254.7699 2318.5398 2256.9791 2274.2181 2562.1817 5 b
令人惊讶的是,@ akrun dplyr解决方案的速度快了10倍……至少让我感到惊讶。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.