R:根据匹配键重新编码多列
R: recode multiple columns based on matching a key
我有一个包含多列的数据框和一个向量,其中包含每列正确答案的键。
ID <- c("ID1","ID2","ID3","ID4")
A <- c(1,3,2,1)
B <- c(3,2,2,3)
C <- c(1,2,2,2)
D <- c(3,3,1,2)
df <- data.frame(ID,A,B,C,D)
df
# ID A B C D
# 1 ID1 1 3 1 3
# 2 ID2 3 2 2 3
# 3 ID3 2 2 2 1
# 4 ID4 1 3 2 2
key <- c(1,2,2,3)
我想重新编码数据帧,如果列中的数据点与键中该列的正确答案匹配,则输出为 1,如果不匹配,则输出为 0。我的因此,所需的输出将如下所示:
# ID A B C D
# 1 ID1 1 0 0 1
# 2 ID2 0 1 1 1
# 3 ID3 0 1 1 0
# 4 ID4 1 0 1 0
我更喜欢可以一次对所有列执行此操作的代码,因为我的实际数据集的列比这多得多。我猜 lapply
可以工作,但我不知道如何迭代它以便键向量中的每个元素与数据框中的正确列匹配。谢谢!
我们可以复制 key
然后做 ==
来创建一个逻辑矩阵,用 +
将它强制转换为二进制(没有使用包)
df[-1] <- +( df[-1] == key[col(df[-1])])
-输出
df
# ID A B C D
#1 ID1 1 0 0 1
#2 ID2 0 1 1 1
#3 ID3 0 1 1 0
#4 ID4 1 0 1 0
一个策略 tidyverse
ID <- c("ID1","ID2","ID3","ID4")
A <- c(1,3,2,1)
B <- c(3,2,2,3)
C <- c(1,2,2,2)
D <- c(3,3,1,2)
df <- data.frame(ID,A,B,C,D)
df
#> ID A B C D
#> 1 ID1 1 3 1 3
#> 2 ID2 3 2 2 3
#> 3 ID3 2 2 2 1
#> 4 ID4 1 3 2 2
key <- c(1,2,2,3)
library(tidyverse)
df %>% nest(attempt = c(A, B, C, D)) %>%
mutate(new = map(attempt, ~setNames(+(.x == key), LETTERS[1:4])),
score = map_int(attempt, ~ sum(.x == key))) %>%
unnest_wider(new)
#> # A tibble: 4 x 7
#> ID attempt A B C D score
#> <chr> <list> <int> <int> <int> <int> <int>
#> 1 ID1 <tibble[,4] [1 x 4]> 1 0 0 1 2
#> 2 ID2 <tibble[,4] [1 x 4]> 0 1 1 1 3
#> 3 ID3 <tibble[,4] [1 x 4]> 0 1 1 0 2
#> 4 ID4 <tibble[,4] [1 x 4]> 1 0 1 0 2
由 reprex package (v2.0.0)
于 2021-04-28 创建
我有一个包含多列的数据框和一个向量,其中包含每列正确答案的键。
ID <- c("ID1","ID2","ID3","ID4")
A <- c(1,3,2,1)
B <- c(3,2,2,3)
C <- c(1,2,2,2)
D <- c(3,3,1,2)
df <- data.frame(ID,A,B,C,D)
df
# ID A B C D
# 1 ID1 1 3 1 3
# 2 ID2 3 2 2 3
# 3 ID3 2 2 2 1
# 4 ID4 1 3 2 2
key <- c(1,2,2,3)
我想重新编码数据帧,如果列中的数据点与键中该列的正确答案匹配,则输出为 1,如果不匹配,则输出为 0。我的因此,所需的输出将如下所示:
# ID A B C D
# 1 ID1 1 0 0 1
# 2 ID2 0 1 1 1
# 3 ID3 0 1 1 0
# 4 ID4 1 0 1 0
我更喜欢可以一次对所有列执行此操作的代码,因为我的实际数据集的列比这多得多。我猜 lapply
可以工作,但我不知道如何迭代它以便键向量中的每个元素与数据框中的正确列匹配。谢谢!
我们可以复制 key
然后做 ==
来创建一个逻辑矩阵,用 +
将它强制转换为二进制(没有使用包)
df[-1] <- +( df[-1] == key[col(df[-1])])
-输出
df
# ID A B C D
#1 ID1 1 0 0 1
#2 ID2 0 1 1 1
#3 ID3 0 1 1 0
#4 ID4 1 0 1 0
一个策略 tidyverse
ID <- c("ID1","ID2","ID3","ID4")
A <- c(1,3,2,1)
B <- c(3,2,2,3)
C <- c(1,2,2,2)
D <- c(3,3,1,2)
df <- data.frame(ID,A,B,C,D)
df
#> ID A B C D
#> 1 ID1 1 3 1 3
#> 2 ID2 3 2 2 3
#> 3 ID3 2 2 2 1
#> 4 ID4 1 3 2 2
key <- c(1,2,2,3)
library(tidyverse)
df %>% nest(attempt = c(A, B, C, D)) %>%
mutate(new = map(attempt, ~setNames(+(.x == key), LETTERS[1:4])),
score = map_int(attempt, ~ sum(.x == key))) %>%
unnest_wider(new)
#> # A tibble: 4 x 7
#> ID attempt A B C D score
#> <chr> <list> <int> <int> <int> <int> <int>
#> 1 ID1 <tibble[,4] [1 x 4]> 1 0 0 1 2
#> 2 ID2 <tibble[,4] [1 x 4]> 0 1 1 1 3
#> 3 ID3 <tibble[,4] [1 x 4]> 0 1 1 0 2
#> 4 ID4 <tibble[,4] [1 x 4]> 1 0 1 0 2
由 reprex package (v2.0.0)
于 2021-04-28 创建