如何在R中按组向量求和?
假设我有这样一个数据帧:如何在R中按组向量求和?,r,R,假设我有这样一个数据帧: df<-data.frame(A.1=1:5,B.1=2:6,C.1=3:7, D.2=4:8,E.2=5:9,F.2=6:10) df A.1 B.1 C.1 D.2 E.2 F.2 1 1 2 3 4 5 6 2 2 3 4 5 6 7 3 3 4 5 6 7 8 4 4 5 6 7 8 9 5 5 6 7 8
df<-data.frame(A.1=1:5,B.1=2:6,C.1=3:7,
D.2=4:8,E.2=5:9,F.2=6:10)
df
A.1 B.1 C.1 D.2 E.2 F.2
1 1 2 3 4 5 6
2 2 3 4 5 6 7
3 3 4 5 6 7 8
4 4 5 6 7 8 9
5 5 6 7 8 9 10
我的真实数据集有来自18个组的超过110K的
cols
,并且会找到一种优雅而简单的方法来实现它。因为数据的方式。帧的结构是内部的,行操作通常比列操作慢得多。考虑到您对该data.frame
实际大小的评论,我可能会使用data.table
将其转换为long,将组作为其自身变量隔离,并执行分组求和
df1:1A.1
#>2:2A.12
#>3:3 A.13
#>4:4 A.14
#>5:5 A.15
#>6:1B.16
#>7:2 B.17
#>8:3B.18
#>9:4B.19
#>10:5 B.110
#>11:1 C.2 11
#>12:2c.212
#>13:3 C.2 13
#>14:4 C.2 14
#>15:5 C.2 15
#>16:1 D.2 16
#>17:2d.217
#>18:3 D.2 18
#>19:4 D.2 19
#>20:5 D.2 20
创建一个新的组
列,该列在新的“变量”列(^.*.\\。
是从字符串开头到第一个“.”的所有内容;gsub(pattern,“,variable)
从变量
中删除模式
)
df_long[,group:=as.integer(gsub(“^.*?\\.”,“”,variable))]
德福朗
#>行数变量值组
#>1:1A.11
#>2:2A.11
#>3:3 A.1 3 1
#>4:4 A.1 4 1
#>5:5 A.1 5 1
#>6:1 B.16 1
#>7:2 B.17 1
#>8:3B.1881
#>9:4B.1191
#>10:5B.1101
#>11:1 C.2 11 2
#>12:2c.2122
#>13:3 C.2 13 2
#>14:4 C.2142
#>15:5 C.2 15 2
#>16:1 D.2 16 2
#>17:2d.2172
#>18:3 D.2 18 2
#>19:4 D.2 19 2
#>20:5D.2202
最后,按行数
和组
进行分组。
这些类型的操作在数据表中的速度非常快,大大快于base R
df_long[,sum(value),by=列表(行号,组)]
#>行号组V1
#> 1: 1 1 7
#> 2: 2 1 9
#> 3: 3 1 11
#> 4: 4 1 13
#> 5: 5 1 15
#> 6: 1 2 27
#> 7: 2 2 29
#> 8: 3 2 31
#> 9: 4 2 33
#> 10: 5 2 35
rowsum
可以执行以下操作:
t(rowsum(t(df), c(1,1,1,2,2,2)))
1 2
[1,] 6 15
[2,] 9 18
[3,] 12 21
[4,] 15 24
[5,] 18 27
(无论出于何种原因,都不存在colsum
)使用库dplyr
和重塑2
。您可以逐行执行每一行(不带尾随%>%来理解转换。基本思想是将
转换成整齐(高)的格式来处理行,然后dcast
将其转换回宽格式
library(dplyr)
library(reshape2)
df %>%
# assign a row number for later grouping
mutate(rn=row_number()) %>%
# make into a tall data frame, with rn as the row key
melt(id.vars = "rn") %>%
# calculate the row suffix for grouping
mutate(suffix = str_extract(variable, "\\d+")) %>%
# put it back into a dataframe, summing value (could use acast if you want an array)
dcast(rn ~ suffix, value.var="value", fun.aggregate = sum)
# rn 1 2
# 1 1 6 15
# 2 2 9 18
# 3 3 12 21
# 4 4 15 24
# 5 5 18 27
使用dplyr
:
df %>%
mutate(ones = rowSums(select(., grep(".1", names(.), value = TRUE))),
twos = rowSums(select(., grep(".2", names(.), value = TRUE)))) %>%
select(ones, twos)
ones twos
1 6 15
2 9 18
3 12 21
4 15 24
5 18 27
dim是33694 x 166438压缩的一个是500米我给了你一个大拇指你的建议。ThanksI创建了一个向量代替@李哲源 类似这样的data.frame(lappy(split.default(df,sub('^.\\.','',names(df))),rowSums))
df %>%
mutate(ones = rowSums(select(., grep(".1", names(.), value = TRUE))),
twos = rowSums(select(., grep(".2", names(.), value = TRUE)))) %>%
select(ones, twos)
ones twos
1 6 15
2 9 18
3 12 21
4 15 24
5 18 27