我有这些数据:
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,],则表示(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个因子水平的值的平均值)。我怎么解决这个问题?谢谢你的帮助。
答案 0 :(得分:0)
在你的第一个函数实例中,
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值的数据集 也许这对你有用。 (有办法解决这个问题, 但是,如果你需要它更强大。如果是这样,那就好了。)