【问题标题】:Rearranging data to a matrix for contour plot将数据重新排列为等高线图的矩阵
【发布时间】:2014-06-10 15:25:50
【问题描述】:

我有这个数据:

df = structure(list(vint1 = c(10L, 1L, 1L, 1L, 7L, 10L, 7L, 1L, 8L, 
3L, 7L, 9L, 1L, 5L, 5L), vint2 = c(3L, 4L, 4L, 1L, 3L, 4L, 6L, 
5L, 6L, 3L, 10L, 4L, 1L, 8L, 8L), vnum1 = c(-1.17289752533732, 
-0.559339864207054, -0.595443000061417, -0.396535659893954, 0.788141517690765, 
-0.655833840195406, -2.26371235489487, -1.34850886354386, -0.0218824069117636, 
0.554324892501117, 2.37117531121636, 0.248289029610446, -1.21942427707135, 
-1.4366686196659, -2.64837580107992)), .Names = c("vint1", "vint2", 
"vnum1"), class = "data.frame", row.names = c(NA, -15L))

当我在 R 提示符下给出以下命令时,它可以工作:

with(df[vint1==10 & vint2==3,], mean(vnum1))  

[1]-1.172898

但是下面的函数给出了错误的结果:

testfn = function(df2, a,b,c)
{
    with(df2[df2[[a]]==10 & df2[[b]]==3,], mean(df2[[c]]))
}

当我下达命令时:

testfn(df,1,2,3)

[1] -0.5571128

这个值是第 3 列 (vnum1) 中所有条目的平均值

mean(df$vnum1)
[1] -0.5571128

以下功能也不起作用:

testfn = function(df2, name1,name2,name3)
{
    with(df2[name1==10 & name2==3,], mean(name3))
}

如果我使用: with(df2[df2$name1==10 & df$name2==3,], mean(df2$name3)) 我得到错误: 参数不是数字或逻辑:返回 NA

我必须随后将此值分配给一个创建矩阵,该矩阵可用于创建等高线图:

mycontour = function(df2, a,b,c)
{
    mymat = matrix(0,10,10)
    for(i in 1:10)   for(j in 1:10)
        mymat[i,j]= with(df2[df2[[a]]==i & df2[[b]]==j,], mean(df2[[c]]))
    filled.contour(mymat)
}  

这应该创建一个等高线图,其中两个有序数字 (1:10) 变量作为 x 和 y 轴,以及根据第三个(数字)变量(对应于 2 个因子水平的值的平均值)的等高线图。我该如何解决这个问题?谢谢你的帮助。

【问题讨论】:

  • 您的第一个with 命令不起作用(vint1vint2 未在df 之外定义);也许使用mean( df[df$vint1==10 & df$vint2==3, 'vnum1'] )(多种方式之一)。此外,在第一个函数定义中,with 不会为您做任何事情。
  • 您是否获得了很多 NaN 值?我是。循环时第一列中没有 2。
  • 感谢您的 cmets。代码: mean(df2[df2[[a]]==i & df2[[b]]==j, c]) 效果很好。

标签: r plot


【解决方案1】:

在您的函数的第一个实例中,

testfn = function(df2, a,b,c)
{
    with(df2[df2[[a]]==10 & df2[[b]]==3,], mean(df2[[c]]))
}

with 根本没有为你做任何事情。您也可以使用:

testfn2 <- function(df2, a,b,c) {
    mean(df2[df2[[a]]==10 & df2[[b]]==3, c])
}
testfn2(df,1,2,3)
## [1] -1.172898

如果您希望在函数参数中使用名称,则需要 做一些替代魔法。为此,我会谦虚地把你推荐给哈德利 威克姆的Subsetting 页面 以获得详尽的解释。

要创建矩阵,您对with 的使用再次无济于事。试试这个:

mycontour2 <- function(df2, a,b,c) {
    nr <- 10 ; nc <- 10
    mm <- matrix(0, nr=nr, nc=nc)
    for (i in 1:nr)
        for (j in 1:nc)
            mm[i,j] <- mean(df2[df2[[a]]==i & df2[[b]]==j, c])
    mm[is.nan(mm)] <- 0
    mm
}
round(mycontour2(df, 1,2,3), digits=2)
##       [,1] [,2]  [,3]  [,4]  [,5]  [,6] [,7]  [,8] [,9] [,10]
##  [1,] -0.81    0  0.00 -0.58 -1.35  0.00    0  0.00    0  0.00
##  [2,]  0.00    0  0.00  0.00  0.00  0.00    0  0.00    0  0.00
##  [3,]  0.00    0  0.55  0.00  0.00  0.00    0  0.00    0  0.00
##  [4,]  0.00    0  0.00  0.00  0.00  0.00    0  0.00    0  0.00
##  [5,]  0.00    0  0.00  0.00  0.00  0.00    0 -2.04    0  0.00
##  [6,]  0.00    0  0.00  0.00  0.00  0.00    0  0.00    0  0.00
##  [7,]  0.00    0  0.79  0.00  0.00 -2.26    0  0.00    0  2.37
##  [8,]  0.00    0  0.00  0.00  0.00 -0.02    0  0.00    0  0.00
##  [9,]  0.00    0  0.00  0.25  0.00  0.00    0  0.00    0  0.00
## [10,]  0.00    0 -1.17 -0.66  0.00  0.00    0  0.00    0  0.00

另一种接近但不包括缺失索引的方式:

require(reshape2)
round(acast(df, vint1 ~ vint2, value.var='vnum1', fun.aggregate=mean, fill=0), digits=3)
##       1     3     4     5     6     8   10
## 1  -0.81  0.00 -0.58 -1.35  0.00  0.00 0.00
## 3   0.00  0.55  0.00  0.00  0.00  0.00 0.00
## 5   0.00  0.00  0.00  0.00  0.00 -2.04 0.00
## 7   0.00  0.79  0.00  0.00 -2.26  0.00 2.37
## 8   0.00  0.00  0.00  0.00 -0.02  0.00 0.00
## 9   0.00  0.00  0.25  0.00  0.00  0.00 0.00
## 10  0.00 -1.17 -0.66  0.00  0.00  0.00 0.00

请注意,第 2 列和第 7 列缺失,第 2、4 和 6 行也缺失,所有 其中前一个矩阵中的零。如果你有更大的 您没有丢失任何 x 或 y 值的数据集,然后 也许这对你有用。 (有办法解决这个问题, 但是,如果您需要它更健壮。如果是这样,请大声疾呼。)

【讨论】:

  • 谢谢。您的解决方案: mean(df2[df2[[a]]==i & df2[[b]]==j, c]) 效果很好。
猜你喜欢
  • 2021-07-17
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多