我有一个数据集,它有两个变量,一个字符和一个数字:
structure(list(ID = c("A", "B", "C", "D", "E", "A", "B", "C",
"D", "E", "A", "B", "C", "D", "E", "A", "B", "C", "D", "E"),
value = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20)), class = "data.frame", row.names = c(NA,
-20L))
我想做的是切换";值";在每组";A";以及";E〃;对于每个序列的";A";以及";E";。
因此,我的最终输出应该是这样的:
ID value
A 5
B 2
C 3
D 4
E 1
A 10
B 7
C 8
D 9
E 6
A 15
B 12
C 13
D 14
E 11
A 20
B 17
C 18
D 19
E 16
我在这里使用了一个数字序列,只是为了简化示例,但我的实际值不是1到20的序列。因此,具有数字模式的解决方案在我的数据中不起作用。
谢谢!
在基本R中,您可以执行以下操作:
# matrix with indices of A's and E's in its two rows
ae <- matrix(which(df$ID %in% c('A', 'E')), nrow=2)
# switch A and E
df$value[ae] <- df$value[ae[2:1, ]]
df
# ID value
# 1 A 5
# 2 B 2
# 3 C 3
# 4 D 4
# 5 E 1
# 6 A 10
# 7 B 7
# 8 C 8
# 9 D 9
# 10 E 6
# 11 A 15
# 12 B 12
# 13 C 13
# 14 D 14
# 15 E 11
# 16 A 20
# 17 B 17
# 18 C 18
# 19 D 19
# 20 E 16
以下是dplyr
与case_when
:的方法
library(dplyr)
df %>%
group_by(gp = cumsum(ID == 'A')) %>%
mutate(value = case_when(ID == "A" ~ value[ID == "E"],
ID == "E" ~ value[ID == "A"],
TRUE ~ value)) %>%
ungroup() %>%
select(-gp)
输出
# A tibble: 20 × 2
ID value
<chr> <dbl>
1 A 5
2 B 2
3 C 3
4 D 4
5 E 1
6 A 10
7 B 7
8 C 8
9 D 9
10 E 6
11 A 15
12 B 12
13 C 13
14 D 14
15 E 11
16 A 20
17 B 17
18 C 18
19 D 19
20 E 16
也许只切换ID:更好
df$ID <- ifelse(df$ID == "A", "E", ifelse(df$ID == "E", "A", df$ID))
使用data.table,在"A";以及";E";,然后使用矢量化索引来更新value
:
library(data.table)
setDT(df)[ID %chin% c("A", "E"), value := value[1:.N + c(1, -1)]][]
#> ID value
#> 1: A 5
#> 2: B 2
#> 3: C 3
#> 4: D 4
#> 5: E 1
#> 6: A 10
#> 7: B 7
#> 8: C 8
#> 9: D 9
#> 10: E 6
#> 11: A 15
#> 12: B 12
#> 13: C 13
#> 14: D 14
#> 15: E 11
#> 16: A 20
#> 17: B 17
#> 18: C 18
#> 19: D 19
#> 20: E 16
可能使用较短的代码,但这里有一个建议
library(tidyverse)
df %>%
pivot_wider(names_from = ID,
values_from = value) %>%
unnest(everything()) %>%
transform(A = E,
E = A) %>%
pivot_longer(cols = everything())
# A tibble: 20 x 2
name value
<chr> <dbl>
1 A 5
2 B 2
3 C 3
4 D 4
5 E 1
6 A 10
7 B 7
8 C 8
9 D 9
10 E 6
11 A 15
12 B 12
13 C 13
14 D 14
15 E 11
16 A 20
17 B 17
18 C 18
19 D 19
20 E 16
我只是简单地切换它们。看起来这可能更花哨,但我会保持简单。
vA <- df$value[df$ID == "A"]
vE <- df$value[df$ID == "E"]
df$value[df$ID == "A"] <- vE
df$value[df$ID == "E"] <- vA
df
#> ID value
#> 1 A 5
#> 2 B 2
#> 3 C 3
#> 4 D 4
#> 5 E 1
#> 6 A 10
#> 7 B 7
#> 8 C 8
#> 9 D 9
#> 10 E 6
#> 11 A 15
#> 12 B 12
#> 13 C 13
#> 14 D 14
#> 15 E 11
#> 16 A 20
#> 17 B 17
#> 18 C 18
#> 19 D 19
#> 20 E 16