I'm looking for a more efficient way to swap two values within a variable. In the dataframe, each respondent has a unique id
.
set.seed(1234)
test <- data.frame(
id = sample(1:10),
value = 21:30
)
test
id value
1 10 21
2 6 22
3 5 23
4 4 24
5 1 25
6 8 26
7 2 27
8 7 28
9 9 29
10 3 30
Assume id
6 and 3 are misplaced; 6 should be in row 10 and 3 should be in row 2.
Note that the sequence of id is not fixed. (The seed here is only for replication.) I always use a temp id to address this issue.
test$id[test$id == 6] <- 999 # Not a real id
test$id[test$id == 3] <- 6
test$id[test$id == 999] <- 3
id value
1 10 21
2 3 22
3 5 23
4 4 24
5 1 25
6 8 26
7 2 27
8 7 28
9 9 29
10 6 30
I know match
or grep
can accomplish this as well.
pos_six <- match(6, test$id)
test$id[match(3, test$id)] <- 6
test$id[pos_six] <- 3
id value
1 10 21
2 3 22
3 5 23
4 4 24
5 1 25
6 8 26
7 2 27
8 7 28
9 9 29
10 6 30
It is not challenging. However, I am still interested in exploring different, more elegant approaches.
Update:
I am seeking answers to fulfill one of the following:
You can swap values with foo[c(i, j)] <- foo[c(j, i)]
, e.g.
test <- data.frame(id = 10:1, value = 21:30)
idx <- match(c(3, 6), test$id);
within(test, id[idx] <- id[rev(idx)])
#> id value
#> 1 10 21
#> 2 9 22
#> 3 8 23
#> 4 7 24
#> 5 3 25
#> 6 5 26
#> 7 4 27
#> 8 6 28
#> 9 2 29
#> 10 1 30
Created on 2025-01-21 with reprex v2.1.1