【发布时间】:2021-11-20 20:30:49
【问题描述】:
假设我有一个包含矩阵列的 data.frame。我想将这些转换为单独的列。我见过this question here,这表明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 保留类型但丢失列名。
【问题讨论】: