我在数据框中有我的数据如下:
someName someID 1 2 3
A 1 T7(P),M6(O),S6(P) T7(P),M6(O),S6(P) T7(P),M6(O),S6(P),S7(P)
B 2 S4(P) S4(P) NA
C 3 S1(P),Q9(D) S1(P),Q9(D) S16(P),Q9(D)
D 4 S5(P),C7(C),S4(P) S4(P),C7(C),S4(P) S5(P),C7(C),S14(P)
E 5 S18(P) S18(P) S18(P)
F 6 S1(P) NA S1(P)
L 8 Z1(P) NA NA
Z 9 NA NA Q100(P)
我想阅读df1
中的每一行,找到拆分元素的完全匹配并计算它们。
然后在新列cbind
中显示总计df1
。
例如在行someName=A
中,我想在逗号上分割第1,2,3列中的字符串,并查找在所有3中找到的T7(P)
,因此总和将为3。 S6(P)
也是如此。因此3+3=6
的总计为row A
。 (S7(P)
被忽略,因为在任何其他列中都找不到它。
我想忽略没有(P)
的任何其他项目,因此忽略M6(O)
。
Row L
总共会有0,因为它不会与任何其他列相交。
所以我可以使用apply
函数逐行进行,然后按,
那么我如何跨分割值进行交叉或匹配?
我的dput(df1)
是:
structure(list(someName = structure(1:8, .Label = c("A", "B",
"C", "D", "E", "F", "L", "Z"), class = "factor"), someID = c(1L,
2L, 3L, 4L, 5L, 6L, 8L, 9L), `1` = c("T7(P),M6(O),S6(P)", "S4(P)",
"S1(P),Q9(D)", "S5(P),C7(C),S4(P)", "S18(P)", "S1(P)", "Z1(P)",
NA), `2` = c("T7(P),M6(O),S6(P)", "S4(P)", "S1(P),Q9(D)", "S4(P),C7(C),S4(P)",
"S18(P)", NA, NA, NA), `3` = c("T7(P),M6(O),S6(P),S7(P)", NA,
"S16(P),Q9(D)", "S5(P),C7(C),S14(P)", "S18(P)", "S1(P)", NA,
"Q100(P)")), .Names = c("someName", "someID", "1", "2", "3"), row.names = c(NA,
-8L), class = "data.frame")
答案 0 :(得分:3)
尝试,假设您的data.frame
被称为test
:
# collapse and split them up
splts <- strsplit(apply(test[3:5],1,function(x) paste(x,collapse=",")),",")
# remove all the non (P) cases
splts <- mapply(function(x,y) x[y], splts, lapply(splts, function(x) grep("(P)",x,fixed=TRUE)))
# sum up those that appear more than once
test$sumtext <- sapply(splts,function(x) sum(table(x)[table(x)>1]))
结果:
> test[,c(1,2,6)]
someName someID sumtext
1 A 1 6
2 B 2 2
3 C 3 2
4 D 4 5
5 E 5 3
6 F 6 2
7 L 8 0
8 Z 9 0
答案 1 :(得分:3)
这是另一种使用正则表达式和table
的方法。我们的想法是从每一行中提取具有特定模式 [A-Z] [0-9] + (P)的元素,并在它们出现多次时计算它们。
apply(dat,1,function(xx){
tab <- table(unlist(regmatches(xx,gregexpr('[A-Z][0-9]+\\(P\\)',xx))))
sum(tab[tab>1])
})
[ 1] 6 2 2 5 3 2 0 0