小伙伴说他写个CSV文件,名字就变了,无缘无故|
就被改了,还有些名字被强加了X
。我注意到了他写的对象是data.frame(d)
,这锅绝对是data.frame
的。
我们可以试一下:
> d = matrix(rnorm(4), ncol=2)
> colnames(d) = c('A|B', '123')
> write.csv(data.frame(d))
'','A.B','X123'
'1',-0.601247669017546,0.802654193340092
'2',-0.128752028398414,0.430829592244036
没错,自己给变了。来一张Drag Queen, 真的是同一人,你以为你约了个妹纸,结果却是扣脚大叔,R经常干这事🤡
其实如果我们不data.frame
强转的话,一切都是OK的。
> write.csv(d)
'','A|B','123'
'1',-0.601247669017546,0.802654193340092
'2',-0.128752028398414,0.430829592244036
我们不防再试一下,自己转为data.frame
,看看是不是这样,结果必须也是,所以这锅就是data.frame
的。
> d = data.frame(d)
> colnames(d)
[1] 'A.B' 'X123'
解决方案
既然转成data.frame
之后,它变了,那我们就再变回去呗。
> colnames(d) = c('A|B', '123')
> colnames(d)
[1] 'A|B' '123'
> write.csv(d)
'','A|B','123'
'1',-0.601247669017546,0.802654193340092
'2',-0.128752028398414,0.430829592244036
问题到底出在那里?
因为|
是保留字符,还有数字不能当变量名这些,几乎是共识,所以data.frame()
这个函数就不允许它们当名字。但是我们想一想,保留字符出现在字符串中是OK的吧?数字开头的字符串是OK的吧?必须是,而名字必须就只是单纯的字符串吧?必须也是,所以这是两码事,你看我们可以给d
的colnames设置回去就知道了,这些都是合法的!到了这里,我们只能说data.frame()
这个函数死蠢!
第二点,你可能以为是matrix转data.frame才会有这问题, 那我们可以再试一下,data.frame转data.frame,你以为它啥都不干吧,不是的,data.frame()
这个函数,就是会给你改名字,给你惊喜。
> write.csv(data.frame(d))
'','A.B','X123'
'1',-0.601247669017546,0.802654193340092
'2',-0.128752028398414,0.430829592244036
> class(d)
[1] 'data.frame'
如何能够避免这个坑
请使用tibble
:
> tibble::as_data_frame(d) %>% write.csv
'','A|B','123'
'1',-0.601247669017546,0.802654193340092
'2',-0.128752028398414,0.430829592244036
看完你还想看
给赞 给Y叔点个赞 小程序