示例数据:
> mat1 = as.data.frame(matrix(c("D-J10-N1","D-J10-N2","D-J2-N1","D-J2-N2",3,6,5,7,8,4,2,3,4,1,2,3), ncol = 4));
> mat1
V1 V2 V3 V4
1 D-J10-N1 3 8 4
2 D-J10-N2 6 4 1
3 D-J2-N1 5 2 2
4 D-J2-N2 7 3 3
期望的输出:
> results
V1 V2 V3 V4
1 J10 9 12 5
2 J2 12 5 5
所以我需要通过V1的子串将V2加到V4,然后在我的结果中返回这个子串。我可以将我的组定义为:
> groups <- substr(mat1[,1],1,5)
> groups
[1] "D-J10" "D-J10" "D-J2-" "D-J2-"
我想在下面使用了rowum:
> rowsum(mat1,groups, reorder = TRUE)
但是,rowsum似乎只接受组的数值?我已经看过申请家庭功能,但没有找到运气....有关如何解决的任何想法?
非常感谢帮助!!
答案 0 :(得分:2)
设置data.frame
有助于使列类更适合(目前它们都是因素)。
mat1 <- data.frame(V1=c("D-J10-N1","D-J10-N2","D-J2-N1","D-J2-N2"),V2=c(3,6,5,7),V3=c(8,4,2,3),V4=c(4,1,2,3))
然后,您可以使用aggregate
和sub
来挑选您的子字符串:
aggregate(mat1[-1],by=list(sub("D-(J[0-9]+)-[A-Z0-9]+","\\1",mat1$V1)),sum)
Group.1 V2 V3 V4
1 J10 9 12 5
2 J2 12 5 5
答案 1 :(得分:1)
首先,让您的数据略有不同。
mat1 <- data.frame(V1 = c("D-J10-N1","D-J10-N2","D-J2-N1","D-J2-N2"),
V2 = c(3,6,5,7),
V3 = c(8,4,2,3),
V4 = c(4,1,2,3))
如果您查看初始数据的str
,则它们都是字符。这就是为什么rowums erros。
使用strsplit
和lapply
可以帮助您入门:
mat1$new.V1 <- unlist(lapply(strsplit(mat1$V1, '-'), '[', 2))
但是,根据第一列中的数据,您可能希望使用gsub和正则表达式:
gsub('.+-([0-z]+)-.+','\\1',mat1$V1)
或类似的......
然后我会查看plyr
包。
ddply(mat1, .(new.V1), summarise, sums = sum(V2, V3, V4))
或者作为丑陋的oneliner:
ddply(mat1, .(unlist(lapply(strsplit(mat1$V1, '-'), '[', 2))), summarise, sum(V2, V3, V4))
答案 2 :(得分:0)
data.table
包适用于此类聚合。正如其他人所说,我会重新格式化您的数据,如下所示:
library(data.table)
mat1 <- data.table(V1=c("D-J10-N1","D-J10-N2","D-J2-N1","D-J2-N2"),
V2=c(3,6,5,7),
V3=c(8,4,2,3),
V4=c(4,1,2,3),
key="V1")
然后你可以这样总结:
mat1[, lapply(.SD, sum), by=list(V1b=gsub(".*\\-(.*)\\-.*", "\\1", mat1[,V1]))]
# V1b V2 V3 V4
#1: J10 9 12 5
#2: J2 12 5 5
lapply(.SD, sum)
部分对每列进行求和,by
部分按您请求的子字符串对其进行分组(使用gsub
和正则表达式)。