R - 如何根据另一个矩阵中的元素更改一个矩阵中的值
R - How to change values in one Matrix based on elements in another Matrix
我在 R 中有以下协方差矩阵:
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.5 NA -1.8 3.65 -17.96 -26.5
AB-2600 NA 7.18 NA NA NA NA
AB-3500 -1.79 NA 5.4 NA -4.63 NA
AC-0100 3.65 NA NA 4.22 9.8 NA
AD-0100 -17.96 NA -4.63 9.8 5.9 NA
AF-0200 -26.5 NA NA NA NA 4.28
每一列和每一行对应一个足球运动员(即 AB-2000)。因此,AB-2000、AB-2000 的交集给出了该球员表现的方差。一行像AB-2000,AF-0200给出了两个选手表现的协方差。
目前,矩阵显示所有协方差值。但是,并非所有协方差值都很重要。事实上,唯一重要的是两个玩家在那个星期玩同一个游戏(在这种情况下,具有相同的游戏 ID (GID))。
以下table显示某个玩家在某周的GID:
GID PLAYER
3467 AB-2000
3460 AB-2600
3463 AB-3500
3467 AC-0100
3458 AD-0100
3461 AF-0200
当两个玩家具有相同的 GID(例如,玩家 AB-2000 和 AC-0100)时,如何只保留协方差矩阵中的值?
感谢您的帮助!
如果我正确地解释了问题,我认为这可以满足您的要求。我已经给了你几个解决方案,选择你的毒药。第一个依赖于嵌套的 for 循环,如果您确定矩阵是对称的,它可能会很慢并进一步优化。
m <- read.table(header=T, stringsAsFactors=F, text="
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.5 NA -1.8 3.65 -17.96 -26.5
AB-2600 NA 7.18 NA NA NA NA
AB-3500 -1.79 NA 5.4 NA -4.63 NA
AC-0100 3.65 NA NA 4.22 9.8 NA
AD-0100 -17.96 NA -4.63 9.8 5.9 NA
AF-0200 -26.5 NA NA NA NA 4.28
")
p <- read.table(header=T, stringsAsFactors=F, text="
GID PLAYER
3467 AB-2000
3460 AB-2600
3463 AB-3500
3467 AC-0100
3458 AD-0100
3461 AF-0200
")
m_t2 <- cm
names(m_t2) <- row.names(m_t2)
## Replace names with GID:
row_names <- p$GID[which(p$PLAYER == row.names(m_t2))]
col_names <- p$GID[which(p$PLAYER == names(m_t2))]
for (i in 1:nrow(m_t2)) {
m_t2[i, col_names != row_names[i]] <- NA
}
m_t2 <- as.matrix(m_t2)
或者,此解决方案确实依赖于 tidyr
和 dplyr
包,但它对于非常大的数据集应该非常有效:
m <- cm
names(m) <- row.names(m)
m$row_names <- row.names(m)
library(tidyr)
library(dplyr)
d <- m %>%
gather(col_names, "cv", -row_names, convert=T) %>%
left_join(p, by = c("row_names" = "PLAYER")) %>%
mutate(GID_row = GID) %>%
select(-GID) %>%
left_join(p, by=c("col_names" = "PLAYER")) %>%
mutate(GID_col = GID) %>%
mutate(new_cv = ifelse((GID_row == GID_col), cv, NA)) %>%
select(row_names, col_names, new_cv) %>%
spread(col_names, new_cv)
m_t <- as.matrix(d[,-1])
row.names(m_t) <- d[["row_names"]]
两种情况下的解决方案如下所示:
> m_t
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.50 NA NA 3.65 NA NA
AB-2600 NA 7.18 NA NA NA NA
AB-3500 NA NA 5.4 NA NA NA
AC-0100 3.65 NA NA 4.22 NA NA
AD-0100 NA NA NA NA 5.9 NA
AF-0200 NA NA NA NA NA 4.28
我在 R 中有以下协方差矩阵:
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.5 NA -1.8 3.65 -17.96 -26.5
AB-2600 NA 7.18 NA NA NA NA
AB-3500 -1.79 NA 5.4 NA -4.63 NA
AC-0100 3.65 NA NA 4.22 9.8 NA
AD-0100 -17.96 NA -4.63 9.8 5.9 NA
AF-0200 -26.5 NA NA NA NA 4.28
每一列和每一行对应一个足球运动员(即 AB-2000)。因此,AB-2000、AB-2000 的交集给出了该球员表现的方差。一行像AB-2000,AF-0200给出了两个选手表现的协方差。
目前,矩阵显示所有协方差值。但是,并非所有协方差值都很重要。事实上,唯一重要的是两个玩家在那个星期玩同一个游戏(在这种情况下,具有相同的游戏 ID (GID))。
以下table显示某个玩家在某周的GID:
GID PLAYER
3467 AB-2000
3460 AB-2600
3463 AB-3500
3467 AC-0100
3458 AD-0100
3461 AF-0200
当两个玩家具有相同的 GID(例如,玩家 AB-2000 和 AC-0100)时,如何只保留协方差矩阵中的值?
感谢您的帮助!
如果我正确地解释了问题,我认为这可以满足您的要求。我已经给了你几个解决方案,选择你的毒药。第一个依赖于嵌套的 for 循环,如果您确定矩阵是对称的,它可能会很慢并进一步优化。
m <- read.table(header=T, stringsAsFactors=F, text="
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.5 NA -1.8 3.65 -17.96 -26.5
AB-2600 NA 7.18 NA NA NA NA
AB-3500 -1.79 NA 5.4 NA -4.63 NA
AC-0100 3.65 NA NA 4.22 9.8 NA
AD-0100 -17.96 NA -4.63 9.8 5.9 NA
AF-0200 -26.5 NA NA NA NA 4.28
")
p <- read.table(header=T, stringsAsFactors=F, text="
GID PLAYER
3467 AB-2000
3460 AB-2600
3463 AB-3500
3467 AC-0100
3458 AD-0100
3461 AF-0200
")
m_t2 <- cm
names(m_t2) <- row.names(m_t2)
## Replace names with GID:
row_names <- p$GID[which(p$PLAYER == row.names(m_t2))]
col_names <- p$GID[which(p$PLAYER == names(m_t2))]
for (i in 1:nrow(m_t2)) {
m_t2[i, col_names != row_names[i]] <- NA
}
m_t2 <- as.matrix(m_t2)
或者,此解决方案确实依赖于 tidyr
和 dplyr
包,但它对于非常大的数据集应该非常有效:
m <- cm
names(m) <- row.names(m)
m$row_names <- row.names(m)
library(tidyr)
library(dplyr)
d <- m %>%
gather(col_names, "cv", -row_names, convert=T) %>%
left_join(p, by = c("row_names" = "PLAYER")) %>%
mutate(GID_row = GID) %>%
select(-GID) %>%
left_join(p, by=c("col_names" = "PLAYER")) %>%
mutate(GID_col = GID) %>%
mutate(new_cv = ifelse((GID_row == GID_col), cv, NA)) %>%
select(row_names, col_names, new_cv) %>%
spread(col_names, new_cv)
m_t <- as.matrix(d[,-1])
row.names(m_t) <- d[["row_names"]]
两种情况下的解决方案如下所示:
> m_t
AB-2000 AB-2600 AB-3500 AC-0100 AD-0100 AF-0200
AB-2000 6.50 NA NA 3.65 NA NA
AB-2600 NA 7.18 NA NA NA NA
AB-3500 NA NA 5.4 NA NA NA
AC-0100 3.65 NA NA 4.22 NA NA
AD-0100 NA NA NA NA 5.9 NA
AF-0200 NA NA NA NA NA 4.28