R中字符转数值的安全方法及按国计算平均身高的正确性验证
问题描述
我在R中有一个dataframe(其中height列为字符型),数据如下:
sampledf = structure(list(person_name = c("Charlie", "Charlie", "Julia", "Bob", "Fatima", "Erik", "Diana", "Fatima", "Ian", "Julia", "Erik", "Charlie", "Ian", "Ian", "Ian", "Charlie", "Hannah", "Julia", "George", "Julia"), country = c("USA", "Sweden", "India", "USA", "Sweden", "Brazil", "India", "Japan", "Brazil", "USA", "USA", "Japan", "Sweden", "India", "Brazil", "Brazil", "Sweden", "USA", "Japan", "Brazil"), height = c("175 cm", "162cm", "168", "not measured", "155 cm", "height not provided", "180", "declined", "172 cm", "165", "N/A", "178 cm", "150cm", "refuse to share", "169", "177 cm", "182", "173 cm", "unknown", "158 cm")), row.names = c(NA, -20L ), class = "data.frame")
对应的表格预览:
| person_name | country | height |
|---|---|---|
| Charlie | USA | 175 cm |
| Charlie | Sweden | 162cm |
| Julia | India | 168 |
| Bob | USA | not measured |
| Fatima | Sweden | 155 cm |
| Erik | Brazil | height not provided |
| Diana | India | 180 |
| Fatima | Japan | declined |
| Ian | Brazil | 172 cm |
| Julia | USA | 165 |
| Erik | USA | N/A |
| Charlie | Japan | 178 cm |
| Ian | Sweden | 150cm |
| Ian | India | refuse to share |
| Ian | Brazil | 169 |
| Charlie | Brazil | 177 cm |
| Hannah | Sweden | 182 |
| Julia | USA | 173 cm |
| George | Japan | unknown |
| Julia | Brazil | 158 cm |
我需要计算各国的平均身高,想确认使用以下代码将字符型转为数值型后计算平均值是否安全:
sampledf$height = as.numeric(as.character(sampledf$height)) aggregate(height ~ country, data=sampledf, FUN=mean, na.rm=TRUE)
理想状态下,无法转为数值的内容会被设为NA并在求平均时忽略,请问这样的处理是否正确?
分析与解决方案
你的现有代码不正确,不能直接用as.numeric()转换height列。原因是像"175 cm"、"162cm"这类带单位或空格的有效身高字符串,直接转数值会被识别为非数字,返回NA,导致大量有效数据被误丢弃,计算出的平均值完全不准确。
正确的处理步骤应该是先提取字符串中的数字部分,再转为数值型:
方法1:使用base R处理
# 提取所有数字字符,转为数值 sampledf$height_num <- as.numeric(gsub("[^0-9]", "", sampledf$height)) # 计算各国平均身高,忽略NA值 aggregate(height_num ~ country, data = sampledf, FUN = mean, na.rm = TRUE)
方法2:使用stringr包(更直观)
library(stringr) # 提取字符串中的数字部分 sampledf$height_num <- as.numeric(str_extract(sampledf$height, "\\d+")) # 计算平均值 aggregate(height_num ~ country, data = sampledf, FUN = mean, na.rm = TRUE)
两种方法都会把"175 cm"转为175、"162cm"转为162,而像"not measured"、"N/A"这类无效值会被转为NA,配合na.rm=TRUE就能在计算平均值时自动忽略这些无效数据,得到正确的各国平均身高。
内容的提问来源于stack exchange,提问作者nov62024
相关产品推荐
相关产品推荐

