“apply”文档提到“在哪里'X'命名为dimnames,它可以是一个选择维名称的字符向量。”我想在data.frame上仅对特定列使用apply。我可以使用dimnames功能来执行此操作吗?
我意识到我可以将子集()X只包含感兴趣的列,但我想更好地理解“命名的dimnames”。
以下是一些示例代码:
> x <- data.frame(cbind(1,1:10))
> apply(x,2,sum)
X1 X2
10 55
> apply(x,c('X2'),sum)
Error in apply(x, c("X2"), sum) : 'X' must have named dimnames
> dimnames(x)
[[1]]
[1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10"
[[2]]
[1] "X1" "X2"
> names(x)
[1] "X1" "X2"
> names(dimnames(x))
NULL
答案 0 :(得分:4)
如果我理解正确,您只想在某些列上使用apply。这是 not 名为dimnames的内容。矩阵或data.frame上的apply函数始终适用于 all 行或 all 列。命名的dimnames允许您选择按名称使用行或列,而不是“普通”1
和2
:
m <- matrix(1:12,4, dimnames=list(foo=letters[1:4], bar=LETTERS[1:3]))
apply(m, "bar", sum) # Use "bar" instead of 2 to refer to the columns
但是,如果您有要申请的列名,可以先选择这些列来完成:
n <- c("A","C")
apply(m[,n], 2, sum)
# A C
#10 42
命名的dimnames是一个副作用,即dimnames作为列表存储在matrix
或array
的“dimnames”属性中。列表的每个组件对应于一个维度并且可以命名。这可能对多维数组更有用......
对于data.frame
,没有“dimnames”属性。 data.frame
本质上是一个列表,因此列表的“names”属性对应于列名,而额外的“row.names”属性对应于行名。因此,没有地方可以存储dimnames的名称(他们当然可以有一个额外的属性,但他们没有)。当您在data.frame上调用dimnames
函数时,它只是从“row.names”和“names”属性创建一个列表。
答案 1 :(得分:2)
问题在于,由于某种原因,您无法直接操纵x
的dimnames,并且x
将被强制转换为不保留命名dimnames的矩阵。
解决方法是首先强制转换为矩阵,然后命名dimnames,然后使用apply()
> X <- as.matrix(x)
> str(X)
num [1:10, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
- attr(*, "dimnames")=List of 2
..$ : chr [1:10] "1" "2" "3" "4" ...
..$ : chr [1:2] "X1" "X2"
> dimnames(X) <- list(C1 = dimnames(x)[[1]], C2 = dimnames(x)[[2]])
> str(X)
num [1:10, 1:2] 1 1 1 1 1 1 1 1 1 1 ...
- attr(*, "dimnames")=List of 2
..$ C1: chr [1:10] "1" "2" "3" "4" ...
..$ C2: chr [1:2] "X1" "X2"
> apply(X, "C1", mean)
1 2 3 4 5 6 7 8 9 10
1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5
> rowMeans(X)
1 2 3 4 5 6 7 8 9 10
1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5