间接索引的案例

3
这是一个带有四列数值和一列列名的表格。 期望的结果是计算列R,使得: 对于第一行,结果是列D中的第一个值(D是列NC中第一行的值) 对于第二行,结果是列A中的第二个值(A是列NC中第二行的值) 以此类推,对于示例中的所有行。
我尝试了很多不同的方法,无法在这里总结。 如何正确计算列R?
A | B | C | D  | NC| R 
9 | 5 | 5 | 10 | D | 10 
4 | 10 | 5 | 6 | A | 4

set.seed(1)
example <- data.frame(U = seq(10))
example %>%  mutate(A = sample(10,10,replace = TRUE), B = sample(10,10,replace = TRUE), C = sample(10,10,replace = TRUE), D= sample(10,10,replace = TRUE),NC = sample(c("A","B","C","D"),10,replace = TRUE) ) %>% select(A,B,C,D, NC) -> example 

我尝试了很多不同的方法,这里无法总结它们。 如何正确计算列R?
我确实有一个解决方案,但它使用了一个for循环,我希望不使用它。以下是提供解决方案的代码:
for(i in 1:dim(example)[1]) { example$R[i] <- example[[example$NC[i]]][i] }

这个解决方案可能会比较慢。有没有可能做得更好一些?
2个回答

4
example$NC 包含列名,因此 example[example$NC] 将按照 example$NC 中的顺序返回这些列的数据框。
您想要从第一列获取第一个值,从第二列获取第二个值,依此类推。这意味着您可以将数据框转换为矩阵,并取该矩阵的 diag()
example$R  <- diag(as.matrix(example[example$NC]))

这将产生与您的循环相同的输出。
example
#    A  B  C  D NC  R
# 1  9  5  5 10  D 10
# 2  4 10  5  6  A  4
# 3  7  6  2  4  C  2
# 4  1 10 10  4  D  4
# 5  2  7  9 10  B  7
# 6  7  9  1  9  B  9
# 7  2  5  4  7  C  4
# 8  3  5  3  6  C  3
# 9  1  9  6  9  B  9
# 10 5  9 10  8  B  9

1

尝试

example %>%
    mutate(R = .[cbind(seq_len(n()), match(NC, names(.)))])

这提供了

   A  B  C  D NC  R
1  9  5  5 10  D 10
2  4 10  5  6  A  4
3  7  6  2  4  C  2
4  1 10 10  4  D  4
5  2  7  9 10  B  7
6  7  9  1  9  B  9
7  2  5  4  7  C  4
8  3  5  3  6  C  3
9  1  9  6  9  B  9
10 5  9 10  8  B  9

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接