R Dataframe создает новый столбец, объединяющий имена строк и столбцов - PullRequest
0 голосов
/ 28 января 2020

У меня есть матрица сходства (SimMat), которую я преобразовал в кадр данных, записав его в формате .csv и перечитав в окружающую среду.

   A    B   C
A  1   0.3 0.7   
B 0.3   1  0.5   
C 0.7  0.5  1  

Я хочу изменить это так что у меня есть фрейм данных, детализирующий уникальные сравнения и значения, как показано ниже:

Comp  Val
A-A    1
A-B   0.3
A-C   0.7
B-B    1 
B-C   0.5
C-C    1

Кто-нибудь знает, как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 28 января 2020

Используя tidyverse, мы можем получить имена строк в качестве нового столбца, получить данные в длинном формате и объединить имена строк и имена столбцов данных.

library(tidyverse)

df %>%
  #If it is a matrix convert to dataframe
  #as.data.frame() %>%
  rownames_to_column() %>%
  pivot_longer(cols = -rowname) %>%
  unite(name, rowname, name, sep = "-")

#  name  value
#  <chr> <dbl>
#1 A-A     1  
#2 A-B     0.3
#3 A-C     0.7
#4 B-A     0.3
#5 B-B     1  
#6 B-C     0.5
#7 C-A     0.7
#8 C-B     0.5
#9 C-C     1  

Чтобы получить только уникальные значения , мы можем использовать pmin и pmax.

df %>%
  #as.data.frame() %>%
  rownames_to_column() %>%
  pivot_longer(cols = -rowname) %>%
  mutate(newcol1 = pmin(rowname, name), newcol2 = pmax(rowname, name)) %>%
  select(-rowname, -name) %>%
  distinct() %>%
  unite(Comp, newcol1, newcol2, sep = "-")

data

df <- structure(list(A = c(1, 0.3, 0.7), B = c(0.3, 1, 0.5), C = c(0.7, 
0.5, 1)), class = "data.frame", row.names = c("A", "B", "C"))
2 голосов
/ 28 января 2020

Один вариант без использования пакетов

transform(as.data.frame.table(m1), Comp = 
       paste(Var1, Var2, sep="-"), Val = Freq)[c("Comp", "Val")]
#  Comp Val
#1  A-A 1.0
#2  B-A 0.3
#3  C-A 0.7
#4  A-B 0.3
#5  B-B 1.0
#6  C-B 0.5
#7  A-C 0.7
#8  B-C 0.5
#9  C-C 1.0

Или просто скопируйте dimnames и преобразуйте матрицу в вектор с c

data.frame(Comp = paste(row.names(m1)[row(m1)],
              colnames(m1)[col(m1)], sep= '-'), Val = c(m1))

Если мы только lower.triangular значения

Val <- m1[lower.tri(m1, diag = TRUE)]
Comp <- paste(row.names(m1)[col(m1)],
              colnames(m1)[row(m1)], sep= '-')[lower.tri(m1, diag = TRUE)]
data.frame(Comp, Val)
#  Comp Val
#1  A-A 1.0
#2  A-B 0.3
#3  A-C 0.7
#4  B-B 1.0
#5  B-C 0.5
#6  C-C 1.0

или с использованием tidyverse

library(dplyr)
library(tidyr)
as.data.frame.table(m1) %>%
     unite(Comp, Var1, Var2, sep='-')
#  Comp Freq
#1  A-A  1.0
#2  B-A  0.3
#3  C-A  0.7
#4  A-B  0.3
#5  B-B  1.0
#6  C-B  0.5
#7  A-C  0.7
#8  B-C  0.5
#9  C-C  1.0

или с melt

library(data.table)
setDT(melt(m1))[, Comp := paste(Var1, Var2, sep="-")]

данные

m1 <- structure(c(1, 0.3, 0.7, 0.3, 1, 0.5, 0.7, 0.5, 1), .Dim = c(3L, 
3L), .Dimnames = list(c("A", "B", "C"), c("A", "B", "C")))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...