4

这是一个足够简单的问题,我很惊讶我找不到任何以前问过它的人的参考资料。它与this不同,本讨论也不涵盖它。

我有一个名为 dimnames 的 4-d 矩阵(尺寸 16x10x15x39)(当cast从一个数据帧(例如 csv)获取数据时会发生这种情况。您可以使用 .names(dimnames(matrix))

然后我想用行总数的分数替换列(即第一个维度),所以我这样做:

matrix2 <- apply(matrix1, c(2,3,4), function(x){x/sum(x)})

但现在names(dimnames(matrix2))第一个维度是空白的。其他 dimname 名称已被保留。

那么:我怎样才能apply在一个名为 dimnames 的矩阵上运行并保留所有剩余维度的名称?

一个可重现的例子

这是问题的简单示例。只需运行整个代码并查看最后两行。

x <- data.frame(
  name=c("bob","james","sarah","bob","james",
         "sarah","bob","james","sarah","bob",
         "james","sarah"),
  year=c("1995","1995","1995","1995","1995",
         "1995","2005","2005","2005","2005",
         "2005","2005"),
  sample_num=c("sample1","sample1","sample1",
               "sample2","sample2","sample2",
               "sample1","sample1","sample1",
               "sample2","sample2","sample2"),
  value=c(1,2,3,2,3,4,1,2,3,2,3,4)
  )
x <- cast(x, sample_num ~ name ~ year)
x_fractions <- apply(y,c(2,3),function(x){x / sum(x)})

names(dimnames(x))
names(dimnames(x_fractions))
4

3 回答 3

2

我不太确定您在寻找什么,但我认为sweep功能非常适合您的目标。尝试:

result <- sweep(test, c(2,3,4), colSums(test), FUN='/')

test@user2068776 创建的数组在哪里。dimnames被保留。

dimnames(result)
$a
[1] "a1" "a2"

$b
[1] "b1" "b2"

$c
[1] "c1" "c2"

$d
[1] "d1" "d2"
于 2013-02-14T14:37:39.763 回答
1

没有可重复的例子来回答问题真的很模棱两可。我回答这个问题,因为在这里制作一个例子很有趣。

dat <- array(rnorm(16*10*15*39))
dim(dat) <- c(16,10,15,39)
dimnames(dat) <- lapply(c(16,10,15,39),
                        function(x) paste('a',sample(1:1000,x,rep=F),sep=''))
dat2 <- apply(dat, c(2,3,4), function(x){x/sum(x)})
identical(dimnames(dat2) ,dimnames(dat))
[1] TRUE

对于 dat 和 dat2,我得到了相同的 dimanmes。所以我肯定在这里想念一些东西。

于 2013-02-14T14:59:20.140 回答
0

我无法使用非强制转换数组重现此行为。您能否提供一个可重现的示例来说明您的数据框/数组的实际外观?否则很难找出问题出在哪里。

这是我用于测试的代码:

# example
a <- c(1,2,11,22)
b <- c(3,4,33,44)
c <- c(5,6,55,66)
d <- c(7,8,77,88)

test <- array(c(a,b,c,d), c(2,2,2,2), dimnames=list(
a=c("a1","a2"),
b=c("b1","b2"),
c=c("c1","c2"),
d=c("d1","d2") )
)
dimnames(test)
names(dimnames(test))

# apply
test2 <- apply(test, c(2,3,4), function(x){
  entry <- sum(x)
})
dimnames(test2)
names(dimnames(test2))

很抱歉将评论“伪装”作为答案。我是 SO 新手,看来您需要更高的代表才能发表评论。

编辑:您dimnames可能会迷路,因为无论出于何种原因,您定义的函数都会产生未命名的结果。您可以尝试另存x/sum(x)为对象(就像我所做的那样),然后在函数中命名该对象。我跳过了最后一部分,因为对我来说没有遗漏names/dimnames

于 2013-02-14T13:17:50.473 回答