R 将空白单元格改为“空白”;不适用;
这是我的数据表 我的目标是将“NA”分配给所有空白单元格,而不考虑类别值或数值。我正在使用na.strings=“”。但它并没有将NA分配给所有空白细胞R 将空白单元格改为“空白”;不适用;,r,na,R,Na,这是我的数据表 我的目标是将“NA”分配给所有空白单元格,而不考虑类别值或数值。我正在使用na.strings=“”。但它并没有将NA分配给所有空白细胞 ## reading the data dat <- read.csv("data2.csv") head(dat) mon hr acc alc sex spd axles door reg cond1 drug1 1 8 21 No Contr
## reading the data
dat <- read.csv("data2.csv")
head(dat)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA D
6 4 20 No Control NA F 30 2 4 Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal <NA> F <NA>
2 Moderate <NA> F <NA>
3 Moderate <NA> M <NA>
4 Complaint <NA> M <NA>
5 Complaint <NA> F <NA>
6 Moderate <NA> M <NA>
## using na.strings
dat2 <- read.csv("data2.csv", header=T, na.strings="")
head(dat2)
mon hr acc alc sex spd axles door reg cond1 drug1
1 8 21 No Control TRUE F 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) A
2 7 20 No Control FALSE M 900 2 2 <NA> Inattentive D
3 3 9 No Control FALSE F 100 2 2 2004 Normal D
4 1 15 No Control FALSE M 0 2 2 <NA> Physical Impairment (Eyes, Ear, Limb) D
5 4 21 No Control FALSE 25 NA NA <NA> <NA> D
6 4 20 No Control NA F 30 2 4 <NA> Drinking Alcohol - Impaired D
inj1 PED_STATE st rac1
1 Fatal NA F NA
2 Moderate NA F NA
3 Moderate NA M NA
4 Complaint NA M NA
5 Complaint NA F NA
6 Moderate NA M NA
读取数据
dat我假设您谈论的是第5行第列“sex”。可能是在data2.csv文件中,单元格包含一个空格,因此R不认为该单元格为空 另外,我注意到在第5行的“axes”和“door”列中,从data2.csv读取的原始值是字符串“NA”。您可能也希望将这些字符串视为na.string。为此,
dat2 <- read.csv("data2.csv", header=T, na.strings=c("","NA"))
您可以使用gsub替换空的多个突变,如“”或空格,即NA:
data= data.frame(cats=c('', ' ', 'meow'), dogs=c("woof", " ", NA))
apply(data, 2, function(x) gsub("^$|^ $", NA, x))
使用
dplyr
的一个更直观的解决方案是
require(dplyr)
## fake blank cells
iris[1,1]=""
## define a helper function
empty_as_na <- function(x){
if("factor" %in% class(x)) x <- as.character(x) ## since ifelse wont work with factors
ifelse(as.character(x)!="", x, NA)
}
## transform all columns
iris %>% mutate_each(funs(empty_as_na))
require(dplyr)
##假空白细胞
虹膜[1,1]=“”
##定义辅助函数
我最近遇到了类似的问题,这对我来说很有效
如果变量是数字的,那么简单的df$Var[df$Var==“”]就不能使用
dat <- read.csv("data2.csv",na.strings=" ",header=TRUE)
dat通过在r中从cran
安装调用dplyr
包
library(dplyr)
(file)$(colname)<-sub("-",NA,file$colname)
库(dplyr)
(file)$(colname)如果您使用haven或foreign包读取外部文件,则My函数将考虑因子、字符向量和潜在属性。它还允许匹配不同的自定义na.string。要转换所有列,只需使用lappy:df[]=lappy(df,blank2na,na.strings=c(“”,'na','na','N/A','N/A','NaN','NaN'))
请参阅更多评论:
#' Replaces blank-ish elements of a factor or character vector to NA
#' @description Replaces blank-ish elements of a factor or character vector to NA
#' @param x a vector of factor or character or any type
#' @param na.strings case sensitive strings that will be coverted to NA. The function will do a trimws(x,'both') before conversion. If NULL, do only trimws, no conversion to NA.
#' @return Returns a vector trimws (always for factor, character) and NA converted (if matching na.strings). Attributes will also be kept ('label','labels', 'value.labels').
#' @seealso \code{\link{ez.nan2na}}
#' @export
blank2na = function(x,na.strings=c('','.','NA','na','N/A','n/a','NaN','nan')) {
if (is.factor(x)) {
lab = attr(x, 'label', exact = T)
labs1 <- attr(x, 'labels', exact = T)
labs2 <- attr(x, 'value.labels', exact = T)
# trimws will convert factor to character
x = trimws(x,'both')
if (! is.null(lab)) lab = trimws(lab,'both')
if (! is.null(labs1)) labs1 = trimws(labs1,'both')
if (! is.null(labs2)) labs2 = trimws(labs2,'both')
if (!is.null(na.strings)) {
# convert to NA
x[x %in% na.strings] = NA
# also remember to remove na.strings from value labels
labs1 = labs1[! labs1 %in% na.strings]
labs2 = labs2[! labs2 %in% na.strings]
}
# the levels will be reset here
x = factor(x)
if (! is.null(lab)) attr(x, 'label') <- lab
if (! is.null(labs1)) attr(x, 'labels') <- labs1
if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
} else if (is.character(x)) {
lab = attr(x, 'label', exact = T)
labs1 <- attr(x, 'labels', exact = T)
labs2 <- attr(x, 'value.labels', exact = T)
# trimws will convert factor to character
x = trimws(x,'both')
if (! is.null(lab)) lab = trimws(lab,'both')
if (! is.null(labs1)) labs1 = trimws(labs1,'both')
if (! is.null(labs2)) labs2 = trimws(labs2,'both')
if (!is.null(na.strings)) {
# convert to NA
x[x %in% na.strings] = NA
# also remember to remove na.strings from value labels
labs1 = labs1[! labs1 %in% na.strings]
labs2 = labs2[! labs2 %in% na.strings]
}
if (! is.null(lab)) attr(x, 'label') <- lab
if (! is.null(labs1)) attr(x, 'labels') <- labs1
if (! is.null(labs2)) attr(x, 'value.labels') <- labs2
} else {
x = x
}
return(x)
}
#”将因子或字符向量的空白元素替换为NA
#“@description将因子或字符向量的空白元素替换为NA
#“@param x因子、字符或任何类型的向量
#“@param na.strings区分大小写的字符串,将转换为na。该函数将在转换之前执行trimws(x,'both')。如果为NULL,则仅执行trimws,不转换为NA。
#“@return返回一个向量trimws(始终用于因子、字符)和已转换的NA(如果匹配NA.strings)。属性也将被保留('label'、'labels'、'value.labels')。
#“@seealse\code{\link{ez.nan2na}”
#“@出口
blank2na=function(x,na.strings=c(“,”,“na”,“na”,“N/A”,“N/A”,“NaN”,“NaN”)){
如果(是系数(x)){
实验室=属性(x,‘标签’,精确=T)
labs1虽然上面的许多选项都运行良好,但我发现将非目标变量强制到chr
是有问题的。在lappy
中使用ifelse
和grepl
可以解决这个偏离目标的效应(在有限的测试中)。在grepl
中使用slarky正则表达式:
set.seed(42)
x1 <- sample(c("a","b"," ", "a a", NA), 10, TRUE)
x2 <- sample(c(rnorm(length(x1),0, 1), NA), length(x1), TRUE)
df <- data.frame(x1, x2, stringsAsFactors = FALSE)
$x1
[1] “角色”
$x2
[1] “numeric”自(dplyr 1.0.0)起,我们可以使用cross()
对于所有列:
dat <- dat %>%
mutate(across(everything(), ~ifelse(.=="", NA, as.character(.))))
dat <- dat %>%
mutate(across(c("Age","Gender"), ~ifelse(.=="", NA, as.character(.))))
原始答案:
您还可以在dplyr
dat <- dat %>%
mutate_at(vars(colnames(.)),
.funs = funs(ifelse(.=="", NA, as.character(.))))
dat%
突变_at(vars(colnames(.)),
.funs=funs(ifelse(.==“”,NA,as.character())
选择要更改的各个列:
dat <- dat %>%
mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]),
.funs = funs(ifelse(.=="", NA, as.character(.))))
dat%
在(vars(colnames(.)[names(.)%in%c(“年龄”、“性别”)])中进行变异,
.funs=funs(ifelse(.==“”,NA,as.character())
这应该可以做到
dat <- dat %>% mutate_all(na_if,"")
dat%mutate\u all(如果“,”则不适用)
对于那些想知道使用data.table方法的解决方案的人,这里是我为之编写的一个函数,可在我的Github上获得:
library(devtools)
source_url("https://github.com/YoannPa/Miscellaneous/blob/master/datatable_pattern_substitution.R?raw=TRUE")
dt.sub(DT = dat2, pattern = "^$|^ $",replacement = NA)
dat2
函数遍历每一列,以确定哪一列包含模式匹配项。然后,gsub()
仅应用于包含模式匹配项的列“^$| ^$”
,用NA
s替换匹配项
我将不断改进此函数以使其更快。我怀疑每个人都已经有了答案,但如果有人来看,dplyr na_if()将(从我的角度来看)比前面提到的更有效:
# Import CSV, convert all 'blank' cells to NA
dat <- read.csv("data2.csv") %>% na_if("")
#导入CSV,将所有“空白”单元格转换为NA
数据%na_如果(“”)
这里是利用readr的read_delim函数的另一种方法。我刚刚学习了(可能广为人知,但我将在这里存档以供将来的用户使用)。这是一种非常直接的方法,比上述方法更通用,因为您可以在csv文件中捕获所有类型的空白值和NA相关值:
dat <- read_csv("data2.csv", na = c("", "NA", "N/A"))
dat这对我很有用
dataset <- read.csv(file = "data.csv",header=TRUE,fill = T,na.strings = "")
dataset我认为data.table是您最好的选择(为了代码的简单性和速度)。以下内容将用NA替换名为“data”的数据集中的所有空格:
data[data==”“]添加一个新库、创建一个新函数如何更直观?我认为您需要ifelse(x%in%c(“,”,“NA”),NA,x)
。将函数与mutate\u一起使用,每个都提供了更大的灵活性和可重用的模式。dplyr
在当今的R-Workflow中无处不在,只是为了让答案更加完整。我认为x!=“
在这里是正确的,因为无论是”“还是”“NA”是空白的。此外,@sclarky的答案对包含数字的数据帧无效,@Badoe的答案并不能真正解决现有data.frames的问题,因此似乎还没有其他答案以通用的方式回答这个问题。我很高兴了解到更好的解决方案。dplyr在当今的R-workflows中无处不在-不,不是。还有什么能解决这个问题“Badoe”并不能真正解决现有数据的问题。框架“甚至意味着?你能在这条语句上扩展一点吗?巴多详细说明了如何配置<代码> Read .CSV < /代码>,以便在从文件读取表时将空白单元格转换为NA。但是,由于标题的标题是“将空白单元格改为“NA””。“完整的答案应该包括data.frame已经在环境中并且用户希望清除空白单元格的情况。这可能不是OP想要的,但它帮助我计算缺失的值,包括空字符串和NAs。df%>%mutate_all(funs(empty_as_na))%%>%summary_all(funs(
dat <- dat %>%
mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]),
.funs = funs(ifelse(.=="", NA, as.character(.))))
dat <- dat %>% mutate_all(na_if,"")
library(devtools)
source_url("https://github.com/YoannPa/Miscellaneous/blob/master/datatable_pattern_substitution.R?raw=TRUE")
dt.sub(DT = dat2, pattern = "^$|^ $",replacement = NA)
dat2
# Import CSV, convert all 'blank' cells to NA
dat <- read.csv("data2.csv") %>% na_if("")
dat <- read_csv("data2.csv", na = c("", "NA", "N/A"))
dataset <- read.csv(file = "data.csv",header=TRUE,fill = T,na.strings = "")
data[data==""] <- NA