问题
I am wanting to split sets of triplicate results into the three possible duplicates.
If the initial set is
A B C
1 122 106 114
2 110 122 110
I want to transform it into
A B
1 122 106
2 122 114
3 106 114
4 110 122
5 110 110
6 122 110
The combn function will do it line by line but I cannot figure out how to apply it across the full dataframe (which can be quite large, I only used two lines for demonstration purposes.).
回答1:
You can do the following:
- Use
lapply()
to apply yourcombn
for each row of the data - Use
rbind
to combine the results - Make use of the magic of
do.call
to combine the list created by steps 1 and 2.
In one line of code:
do.call(rbind, lapply(seq(nrow(dat)), function(i)t(combn(dat[i, ], 2))))
[,1] [,2]
[1,] 122 106
[2,] 122 114
[3,] 106 114
[4,] 110 122
[5,] 110 110
[6,] 122 110
回答2:
Here's another approach. I'll use data.table
s to illustrate the concept. But it should be fairly straightforward using data.frames as well.
require(data.table) ## 1.9.2+
require(reshape2) ## for melt generic
setDT(dat)
r1 = melt(dat, id="A", value.name="B")[, variable := NULL]
rbindlist(list(r1, dat[, list(B,C)]))
# A B
# 1: 122 106
# 2: 110 122
# 3: 122 114
# 4: 110 110
# 5: 106 114
# 6: 122 110
回答3:
Instead of iterating over all rows as suggested by Andrie, you can also iterate over all combinations returned by combn
:
d <- read.table(text="A B C
1 122 106 114
2 110 122 110")
l <- apply(combn(3, 2), 2, function(x) setNames(d[x], c("A", "B")))
do.call(rbind, l)
## A B
## 1 122 106
## 2 110 122
## 11 122 114
## 21 110 110
## 12 106 114
## 22 122 110
This is probably faster than iterating over all rows. The function used in apply
returns the columns of d
currently of interest, and reassigns column names. Inspect l
to see what's happening under the hood.
来源:https://stackoverflow.com/questions/25402561/splitting-triplicates-into-duplicates