从数据框中收集列和行中具有相同名称的值

时间:2019-05-30 19:34:47

标签: r

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语句可以帮助跳过该变量。有人可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

只需遍历每个列/行名(使用sapply),并使用方括号符号表示该行和该列的子集p

sapply(c('a','b','c','e'), function(x) p[x,x])
 a  b  c  e 
 1 22  9 15 

如果您不想预先指定变量名,则可以只使用colnamesrownames

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

首先,将行名称设置为变量,然后从宽到长格式进行收集,最后,仅过滤匹配的行和列对。

相关问题