R 基于逐月随机抽样从矩阵中提取最大值
我有一个距离矩阵df1,显示了8个位置a:h之间的距离R 基于逐月随机抽样从矩阵中提取最大值,r,loops,for-loop,max,R,Loops,For Loop,Max,我有一个距离矩阵df1,显示了8个位置a:h之间的距离 x <- c("a","b","c","d","e","f","g","h") df1 <- data.frame(a=c(0,1,2,3,4,5,6,7), b=c(1,0,1,2,3,4,5,6), c=c(2,1,0,1,2,3,4,5), d=c(3,2,1,0,1,2,3,4), e=c(4,3,2,1,0,1,2,3), f=c(5,4,3,2,
x <- c("a","b","c","d","e","f","g","h")
df1 <- data.frame(a=c(0,1,2,3,4,5,6,7), b=c(1,0,1,2,3,4,5,6),
c=c(2,1,0,1,2,3,4,5), d=c(3,2,1,0,1,2,3,4),
e=c(4,3,2,1,0,1,2,3), f=c(5,4,3,2,1,0,1,2),
g=c(6,5,4,3,2,1,0,1), h=c(7,6,5,4,3,2,1,0),
row.names=x)
> df1
a b c d e f g h
a 0 1 2 3 4 5 6 7
b 1 0 1 2 3 4 5 6
c 2 1 0 1 2 3 4 5
d 3 2 1 0 1 2 3 4
e 4 3 2 1 0 1 2 3
f 5 4 3 2 1 0 1 2
g 6 5 4 3 2 1 0 1
h 7 6 5 4 3 2 1 0
我还想计算每个月地点之间的累积距离,其输出如下:
Month Cum.Distance
1 11 5
2 12 11
3 1 6
我希望这是有道理的。我曾考虑过使用for循环,但我对R循环的了解有限,因此非常感谢您的帮助。非常感谢 首先,我根据您的示例定义数据帧
df2 <- read.table(text = "
Month Location
1 11 c
2 11 a
3 11 d
4 12 f
5 12 c
6 12 f
7 12 a
8 1 b
9 1 b
10 1 h", h = T)
aggregate(Location ~ Month, df2, function(j) diff(range(sapply(j, function(i) grep(i, letters)))))
Month Location
1 1 6
2 11 3
3 12 5
x <- c("a","b","c","d","e","f","g","h")
df1 <- data.frame(a=c(0,1,2,3,4,5,6,7), b=c(1,0,1,2,3,4,5,6),
c=c(2,1,0,1,2,3,4,5), d=c(3,2,1,0,1,2,3,4),
e=c(4,3,2,1,0,1,2,3), f=c(5,4,3,2,1,0,1,2),
g=c(6,5,4,3,2,1,0,1), h=c(7,6,5,4,3,2,1,0),
row.names=x)
df2 <- data.frame(Month=c(rep(11,3),rep(12,4),rep(1,3)),
Location=sample(letters[1:8],10,replace=T))
# Month Location
# 1 11 d
# 2 11 c
# 3 11 h
# 4 12 e
# 5 12 c
# 6 12 b
# 7 12 h
# 8 1 h
# 9 1 g
# 10 1 b
最后,我将该函数应用于df2
中的所有月份,并将其作为数据帧重新打包
# Run function on all months
data.frame(month = unique(df2$Month), max_dist = unlist(lapply(unique(df2$Month), max_dist)))
# month max_dist
# 1 11 5
# 2 12 6
# 3 1 6
以下内容提供了总距离:
tot_dist <- function(m){
tmp <- match(df2$Location[df2$Month == m], rownames(df1))
sum(df1[cbind(head(tmp, -1), tail(tmp, -1))])
}
谢谢你,Len,你知道如何编辑它来计算每个月每个地点之间的累积距离吗?你到底想要什么?您希望应用的月份顺序是什么?我希望按照每个位置在数据框中出现的顺序对它们之间的距离求和。在你的例子中,对于第11个月,累积距离等于从c到a的距离加上从a到d的距离。月份的顺序并不重要,但如果它们保持原来的顺序会很有用。我现在明白了,我已经把它添加到了我的答案中。这与您的第一个目标的代码几乎相同。Hi Ronak df1沿x=y线对称,因此无论是按行还是按列进行计算都不重要。谢谢你,林巴克这真的很有帮助!我的下一个问题是,是否可以计算每个月的累计距离。例如,对于您的示例中所示的df2,第11个月的累积距离将通过将从d到c的距离与从c到h的距离相加来计算,所以(d:c)+(c:h)=6。@EmilyWinter我在我的解决方案中添加了一个函数,可以做到这一点。这很好,谢谢。然而,有一个问题是,当您在df2的新版本上运行max_dist函数时,每个月只包含一个位置记录,它会在这些月内给出错误的输出。使用df2@EmilyWinter尝试一下,我想我已经修复了它。您好,这段代码一直运行得很好,但我想修改它。是否可以计算每个月地点的最大距离和总距离,以及下个月的第一个地点?因此,在您的示例中,将为位置d、c、h和e计算第11个月的最大距离/总距离。提前感谢你的帮助。
x <- c("a","b","c","d","e","f","g","h")
df1 <- data.frame(a=c(0,1,2,3,4,5,6,7), b=c(1,0,1,2,3,4,5,6),
c=c(2,1,0,1,2,3,4,5), d=c(3,2,1,0,1,2,3,4),
e=c(4,3,2,1,0,1,2,3), f=c(5,4,3,2,1,0,1,2),
g=c(6,5,4,3,2,1,0,1), h=c(7,6,5,4,3,2,1,0),
row.names=x)
df2 <- data.frame(Month=c(rep(11,3),rep(12,4),rep(1,3)),
Location=sample(letters[1:8],10,replace=T))
# Month Location
# 1 11 d
# 2 11 c
# 3 11 h
# 4 12 e
# 5 12 c
# 6 12 b
# 7 12 h
# 8 1 h
# 9 1 g
# 10 1 b
# Find maximum distance
max_dist <- function(m){
# Check if it's just one location
if(sum(df2$Month == m) == 1)return(0)
# Get all combinations of locations for given month
tmp <- t(combn(match(df2$Location[df2$Month == m], rownames(df1)), 2))
# Get max value from these location combinations
max(df1[tmp[, 1], tmp[, 2]])
}
# Run function on all months
data.frame(month = unique(df2$Month), max_dist = unlist(lapply(unique(df2$Month), max_dist)))
# month max_dist
# 1 11 5
# 2 12 6
# 3 1 6
tot_dist <- function(m){
tmp <- match(df2$Location[df2$Month == m], rownames(df1))
sum(df1[cbind(head(tmp, -1), tail(tmp, -1))])
}
# Find maximum distance
max_dist <- function(m){
# Check if it's just one location
if(sum(df2$Month == m) == 1)return(0)
# Get all locations
locs <- which(df2$Month == m)
if(tail(which(df2$Month == m), 1) != nrow(df2))locs <- c(locs, tail(which(df2$Month == m), 1) + 1)
# Get all combinations of locations for given month
tmp <- t(combn(match(df2$Location[locs], rownames(df1)), 2))
# Get max value from these location combinations
max(df1[tmp[, 1], tmp[, 2]])
}
tot_dist <- function(m){
# Get all locations
locs <- which(df2$Month == m)
if(tail(which(df2$Month == m), 1) != nrow(df2))locs <- c(locs, tail(which(df2$Month == m), 1) + 1)
tmp <- match(df2$Location[locs], rownames(df1))
sum(df1[cbind(head(tmp, -1), tail(tmp, -1))])
}