This is a small example:
a <- c("a", "b", "f", "c", "e")
b <- c("a", "c", "e", "d", "b")
p <- matrix(1:25, nrow = 5, dimnames = list(a, b))
p <- as.data.frame(p)
#data.frame would be like that
a c e d b
a 1 6 11 16 21
b 2 7 12 17 22
f 3 8 13 18 23
c 4 9 14 19 24
e 5 10 15 20 25
我想要的输出:
score
a 1
b 22
c 9
e 15
这是我写的代码:
L <- rownames(p)
output <- NULL
t <- 1
for (i in L) {
tar_column <- p[i]
score <- tar_column[t, ]
tar_score <- matrix(score, nrow = 1, dimnames = list(i, "score"))
output <- rbind(output, tar_score)
t <- t+1
}
我得到的输出:
score
a 1
b 22
Error in `[.data.frame`(p, i) : undefined columns selected
问题是列名和行名不完全匹配。我认为,如果if语句无法与列名匹配,则if语句可以帮助跳过该变量。有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
只需遍历每个列/行名(使用sapply
),并使用方括号符号表示该行和该列的子集p
:
sapply(c('a','b','c','e'), function(x) p[x,x])
a b c e
1 22 9 15
如果您不想预先指定变量名,则可以只使用colnames
或rownames
:
sapply(colnames(p), function(x) p[x,x])
a c e d b
1 9 15 NA 22
如果没有匹配的行名,则该值将返回NA
。如果需要,可以通过设置结果子集来删除NA值:
result <- sapply(colnames(p), function(x) p[x,x])
result[!is.na(result)]
a c e b
1 9 15 22
答案 1 :(得分:0)
这是另一种选择:
library(tidyverse)
p %>%
rownames_to_column("row") %>%
gather(col, score, -row) %>%
filter(row == col) %>%
select(-row)
#> col score
#> 1 a 1
#> 2 c 9
#> 3 e 15
#> 4 b 22
首先,将行名称设置为变量,然后从宽到长格式进行收集,最后,仅过滤匹配的行和列对。