r语言 - 分割矩阵-列,不需要中间转换为矩阵



假设我有一个包含矩阵列的data.frame。我想把这些变换成单独的列。我在这里看到了这个问题,它给出了as.data.frame(as.matrix(...))的一个很好的解。但是,如果data.frame的列/矩阵列是数字和字符的混合,则转换为矩阵将所有列转换为字符。

我可以通过蛮力,循环在列等,但必须有一个更优雅的方式做到这一点。我玩了像do.call(cbind, sapply(..., data.frame))这样的东西,它实际上保留了数字/字符,但破坏了不太理想的列名(而matrix-data.frame转换使列名看起来很好)。

例如,

> data(mtcars)
> mtcars$car <- row.names(mtcars)
> m <- model.frame(cbind(gear, am) ~ car, data = mtcars)
> head(m)
cbind(gear, am).gear cbind(gear, am).am               car
Mazda RX4                            4                  1         Mazda RX4
Mazda RX4 Wag                        4                  1     Mazda RX4 Wag
Datsun 710                           4                  1        Datsun 710
Hornet 4 Drive                       3                  0    Hornet 4 Drive
Hornet Sportabout                    3                  0 Hornet Sportabout
Valiant                              3                  0           Valiant
> str(m, give.attr = FALSE)
'data.frame':   32 obs. of  2 variables:
$ cbind(gear, am): num [1:32, 1:2] 4 4 4 3 3 3 3 4 4 4 ...
$ car            : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
> dim(m)
[1] 32  2
> m2 <- as.data.frame(as.matrix(m))
> head(m2)
cbind(gear, am).gear cbind(gear, am).am               car
Mazda RX4                            4                  1         Mazda RX4
Mazda RX4 Wag                        4                  1     Mazda RX4 Wag
Datsun 710                           4                  1        Datsun 710
Hornet 4 Drive                       3                  0    Hornet 4 Drive
Hornet Sportabout                    3                  0 Hornet Sportabout
Valiant                              3                  0           Valiant
> str(m2, give.attr = FALSE)
'data.frame':   32 obs. of  3 variables:
$ cbind(gear, am).gear: chr  "4" "4" "4" "3" ...
$ cbind(gear, am).am  : chr  "1" "1" "1" "0" ...
$ car                 : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
> dim(m2)
[1] 32  3
> m3 <- do.call(cbind, sapply(m, data.frame))
> head(m3)
cbind(gear, am).gear cbind(gear, am).am            X..i..
1                    4                  1         Mazda RX4
2                    4                  1     Mazda RX4 Wag
3                    4                  1        Datsun 710
4                    3                  0    Hornet 4 Drive
5                    3                  0 Hornet Sportabout
6                    3                  0           Valiant
> str(m3, give.attr = FALSE)
'data.frame':   32 obs. of  3 variables:
$ cbind(gear, am).gear: num  4 4 4 3 3 3 3 4 4 4 ...
$ cbind(gear, am).am  : num  1 1 1 0 0 0 0 0 0 0 ...
$ X..i..              : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
> dim(m3)
[1] 32  3

本例中,m2保留列名,但不保留类型,m3保留类型,但不保留列名。

使用do.calldata.frame

m4 <- do.call(data.frame, c(m, check.names = FALSE)) 

与产出结构
> str(m4)
'data.frame':   32 obs. of  3 variables:
$ cbind(gear, am).gear: num  4 4 4 3 3 3 3 4 4 4 ...
$ cbind(gear, am).am  : num  1 1 1 0 0 0 0 0 0 0 ...
$ car                 : chr  "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...

在导出'm3'的第三种情况下,OP使用sapply遍历data.frame'm'的列,然后转换为data.frame。但是,它在平坦化方面没有任何作用,即matrix中的列被转换为list中的data.frame,列名中的X..来自内部名称,因为'car',原始'm'中的列被强制转换为没有默认列名的data.frame

> str(sapply(m, data.frame))
List of 2
$ cbind(gear, am):'data.frame':    32 obs. of  2 variables:
..$ gear: num [1:32] 4 4 4 3 3 3 3 4 4 4 ...
..$ am  : num [1:32] 1 1 1 0 0 0 0 0 0 0 ...
$ car            :'data.frame':    32 obs. of  1 variable:
..$ X..i..: chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...

相关内容

最新更新