【问题标题】:Standardizing raw data in R - Missing values标准化 R 中的原始数据 - 缺失值
【发布时间】:2014-05-03 20:55:26
【问题描述】:

我正在尝试将原始数据从文本文件转换为矩阵。我已经使用readLines() 读取了数据,然后使用grepl() (即男性;20;30.5 => “男性”“20”“30.5”)将数据分隔到一个列表中。

唯一的问题是数据缺少一些未记录性别、年龄或体重的值,或者逗号代替了小数点。在这些情况下,数据列表包含如下所示的行:

##"male"    "20"   "55.3"
##"male" "45" 

##"" "55" "55"

我想通过附加NA 来应用一个函数来更正这些实例。然后将该函数应用于lapply(data.dataList, function)R 中的函数不是我的强项,但这是我的第一次尝试:

# function to correct column order for weight data
f.assignFields <- function(x) {
# create a blank character vector of length 3
out <- character(3)
sex <- grepl("[[:alpha:]]",x)
out[1] <- x[sex]
age.num <- which(as.numeric(x) <0)
out[2] <- ifelse(length(length(age.num) > 0, x[age.num], NA)
weight.num <- which(as.numeric(x) > 0)
out[3] <- ifelse(length(weight.num) > 0, x[weight.num], NA)
out
}

data.standardFields <- lapply(data.dataList, fassignFields)

我知道我想把带字母的字符串放在第一列,把其他的放在第二和第四列。我也应该将“,”替换为“。”应用lapply()之前或之后的权重?只需向正确的方向轻推一点,将不胜感激。

编辑: 从文本文件中提取的数据非常小。只有九个人记录了他们的性别、年龄和体重。练习的重点是通过修改和转换数据来处理原始数据,以检查自己修改数据的有用性,而不是使用read.table()

male;28;81.3
male;45;
female; 17 ;57,2
female;64;62.8
male;16;55.3
male;;50,1
female;20.4;55
female;;
;55;55

这就是我所做的:

#read text file
weight.data <- readLines(text.txt)         

#removed white spaces
weight.data <- gsub(" ","",weight.data)
weight.data

[1] "male;28;81.3"     
[2] "male;45;"      
[3] "female;17;57,2"
[4] "female;64;62.8"  
[5] "male;16;55.3"   
[6] "male;;50,1"       
[7] "female;20.4;55"     
[8] "female;;"          
[9] ";55;55" 

#split strings by semicolon
weight.dataList <-strsplit(weight.data, split = ";")
weight.dataList

[[1]]
[1] "male"    "28"   "81.3"

[[2]]
[1] "male" "45"  

[[3]]
[1] "female" "17"     "57,2"  

[[4]]
[1] "female" "64"   "62.8"

[[5]]
[1] "male"  "16"   "55.3"

[[6]]
[1] "male"    ""     "50,1"

[[7]]
[1] "female"    "20.4" "55"  

[[8]]
[1] "female" ""  

[[9]]
[1] ""   "55" "55"

我想将 NA 添加到缺失的行中。我正在尝试创建一个函数来纠正该字段的行尺寸。例如,第二个条目的权重应该是 NA。

# function to correct column order and size for weight data
f.assignFields <- function(x) {
# create a blank character vector of length 3
out <- character(3)
sex <- grepl("[[:alpha:]]",x)
# puts sex in first column
out[1] <- x[sex]
# assigns NA if age missing
age.num <- which(as.numeric(x) <0)
out[2] <- ifelse(length(length(age.num) > 0, x[age.num], NA)
# assigns NA if weight missing
weight.num <- which(as.numeric(x) > 0)
out[3] <- ifelse(length(weight.num) > 0, x[weight.num], NA)
out
}

data.standardFields <- lapply(data.dataList, fassignFields)

最后我将使用unlist()matrix() 将数据转换为行列格式。我想用 NA 替换数据的缺失值,将数据按以下顺序“性别、年龄、体重”并固定权重,使 55,1 显示为 55.1。

【问题讨论】:

  • 一个可重现的示例和所需的输出可能会派上用场
  • 看来你可以只使用 read.table(..., sep=";", fill=T) 什么的。您能否提供更大的原始数据样本。另外,data.dataList 函数从何而来?它期望什么输入?
  • TL;DR - 同时使它更简洁和更具体。

标签: r function raw-data


【解决方案1】:

最简单的方法是使用read.table,但您的教授似乎想折磨您。从来没有任何数据集将 20.4 列为一个人的年龄。

> ## txt <- "male;28;81.3
  ## male;45;
  ## female; 17 ;57,2
  ## female;64;62.8
  ## male;16;55.3
  ## male;;50,1
  ## female;20.4;55
  ## female;;
  ## ;55;55"
> x <- gsub("\\s+", "", readLines(textConnection(txt))) 
> rpl.comma <- gsub(",", ".", x)
> spl <- strsplit(rpl.comma, ";")
> M <- matrix(0, nrow = length(x), ncol = 3)
> for(j in 1:3){
    M[,j] <- sapply(seq(spl), function(i){
      ifelse(spl[[i]][j] == "", "NA", spl[[i]][j])
    })
  }
> DF <- data.frame(M)
> names(DF) <- c("sex", "age", "weight")
> DF
##      sex  age weight
## 1   male   28   81.3
## 2   male   45   <NA>
## 3 female   17   57.2
## 4 female   64   62.8
## 5   male   16   55.3
## 6   male   NA   50.1
## 7 female 20.4     55
## 8 female   NA   <NA>
## 9     NA   55     55

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 2018-04-05
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多