data.frame新增列用[]语法丢失POSIXct类的原因及解决咨询
问题:data.frame中$与[]赋值POSIXct列的类型差异问题
在创建新的data.frame并添加POSIXct类列时,用$语法能正常保留POSIXct类型,但用[]语法时,POSIXct类会丢失,列被自动转成numeric类型。就算显式设置列的类,[]语法也改不了类型,而$就没这个问题。具体代码如下:
rm(dfDummy) # 确保没有残留的旧数据/列 dfDummy <- data.frame(a = 1:10, dummy = dummy) dfDummy$p <- as.POSIXct(NA) dfDummy$p.rep <- as.POSIXct(rep(NA, 10)) dfDummy[ , c("n1", "n2")] <- as.POSIXct(NA) dfDummy[ , c("n1.rep", "n2.rep")] <- as.POSIXct(rep(NA, 10)) sapply(X = c("p", "p.rep", "n1", "n2", "n1.rep", "n2.rep"), function(x) class(dfDummy[, x])) # 即使显式设置类,仍然是"numeric"——问题出在哪? class(dfDummy[ , c("n1", "n2", "n1.rep", "n2.rep")]) <- c("POSIXct", "POSIXt") sapply(X = c("p", "p.rep", "n1", "n2", "n1.rep", "n2.rep"), function(x) class(dfDummy[, x]))
原因说明
1. $和[]赋值的本质区别
- 用
$赋值时,R会直接把右侧的POSIXct对象原封不动加到data.frame里,连带着它的类属性一起保留。因为$是针对单个列的操作,不会对赋值对象做额外转换。 - 但用
[]给多列赋值时,R会先把右侧的对象转成矩阵(为了匹配多列的维度),而POSIXct本质是带类属性的numeric向量,转成矩阵后会丢掉类属性,只剩下底层的数值,所以赋值后列就变成numeric类型了。
2. 显式设置类为啥没用
你直接给dfDummy[, c("n1", ...)]设置类,其实是在修改一个临时提取出来的data.frame子集,这个子集修改后不会同步回原data.frame,所以原列的类型还是numeric。
解决办法
方法1:循环逐个赋值(适合少量列)
如果要通过变量名批量加POSIXct列,循环遍历列名,用[[col]](和$效果一样,还支持变量)赋值就行:
cols_to_add <- c("n1", "n2", "n1.rep", "n2.rep") for(col in cols_to_add) { dfDummy[[col]] <- as.POSIXct(rep(NA, 10)) }
方法2:先建带POSIXct列的data.frame再合并
要批量加多列的话,先单独做一个包含目标列的data.frame,再和原数据合并:
new_cols <- data.frame( n1 = as.POSIXct(rep(NA, 10)), n2 = as.POSIXct(rep(NA, 10)), n1.rep = as.POSIXct(rep(NA, 10)), n2.rep = as.POSIXct(rep(NA, 10)) ) dfDummy <- cbind(dfDummy, new_cols)
这样能保证新列的POSIXct类型完整保留。
方法3:用dplyr的mutate批量添加(可选)
如果常用tidyverse工具,用dplyr::mutate()能更简洁地批量加列,自动保留类型:
library(dplyr) dfDummy <- dfDummy %>% mutate( n1 = as.POSIXct(rep(NA, 10)), n2 = as.POSIXct(rep(NA, 10)), n1.rep = as.POSIXct(rep(NA, 10)), n2.rep = as.POSIXct(rep(NA, 10)) )
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

