빈 셀을 "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 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
나는 당신이 행 5 열 "섹스"에 대해 이야기하고 있다고 가정하고 있습니다. data2.csv 파일에서 셀에 공백이 포함되어 있으므로 R에 의해 비어있는 것으로 간주되지 않는 경우 일 수 있습니다.
또한 행 5 열 "axles"및 "door"에서 data2.csv에서 읽은 원래 값은 문자열 "NA"임을 알았습니다. 아마도 그것들을 na.strings로 취급하고 싶을 것입니다. 이것을하기 위해,
dat2 <- read.csv("data2.csv", header=T, na.strings=c("","NA"))
편집하다:
data2.csv를 다운로드했습니다. 예, 5 행 "sex"열에 공백이 있습니다. 그래서 당신은
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))
열의 하위 집합에만 수정 사항을 적용하려면 dplyr의 열 일치 구문을 사용하여 관심있는 열을 지정할 수 있습니다. 예:mutate_each(funs(empty_as_na), matches("Width"), Species)
테이블에 날짜가 포함되어있는 경우 보다 형식이 안전한 버전을 사용하는 것이 좋습니다.ifelse
최근에 비슷한 문제가 발생했습니다. 이것이 나를 위해 일한 것입니다. 변수가 숫자 df$Var[df$Var == ""] <- "NA"이면 간단한 것으로 충분합니다. 그러나 변수가 요인 인 경우 먼저 문자로 변환 한 다음 ""셀을 원하는 값으로 바꾸고 다시 요인으로 변환해야합니다. 따라서 귀하의 성별 변수가 요인이라고 가정하고 빈 셀을 교체하려면 다음을 수행합니다.
df$Var <- as.character(df$Var)
df$Var[df$Var==""] <- "NA"
df$Var <- as.factor(df$Var)
이것은 트릭을 할 것입니다
dat <- dat %>% mutate_all(na_if,"")
내 함수는 외부 파일을 읽기 위해 haven 또는 foreign 패키지를 사용하는 경우 요인, 문자 벡터 및 잠재적 속성을 고려합니다. 또한 다른 자체 정의 na.string을 일치시킬 수 있습니다. 모든 열을 변환하려면 lappy를 사용하십시오.df[] = lapply(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)
}
While many options above function well, I found coercion of non-target variables to chr problematic. Using ifelse and grepl within lapply resolves this off-target effect (in limited testing). Using slarky's regular expression in grepl:
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)
The problem of coercion to character class:
df2 <- lapply(df, function(x) gsub("^$|^ $", NA, x))
lapply(df2, class)
$x1 [1] "character"
$x2 [1] "character"
Resolution with use of ifelse:
df3 <- lapply(df, function(x) ifelse(grepl("^$|^ $", x)==TRUE, NA, x))
lapply(df3, class)
$x1 [1] "character"
$x2 [1] "numeric"
You can also use mutate_at in dplyr
dat <- dat %>%
mutate_at(vars(colnames(.)),
.funs = funs(ifelse(.=="", NA, as.character(.))))
Select individual columns to change:
dat <- dat %>%
mutate_at(vars(colnames(.)[names(.) %in% c("Age","Gender")]),
.funs = funs(ifelse(.=="", NA, as.character(.))))
As of (dplyr 0.8.0 above) the way this should be written has changed. Before it was, funs() in .funs (funs(name = f(.)). Instead of funs, now we use list (list(name = ~f(.)))
Note that there is also a much simpler way to list the column names ! (both the name of the column and column index work)
dat <- dat %>%
mutate_at(.vars = c("Age","Gender"),
.funs = list(~ifelse(.=="", NA, as.character(.))))
Couldn't you just use
dat <- read.csv("data2.csv",na.strings=" ",header=TRUE)
should convert all blanks to NA as the data are read in be sure to put a space between your quotation
For those wondering about a solution using the data.table way, here is one:
dat2[, lapply(.SD, gsub, pattern = "^$|^ $", replacement = NA),]
lapply go through each rows, and apply the gsub() function on every cell matching the pattern "^$|^ $", to replace their value by a NA.
It would be nice if someone could do a benchmarking to see which approach is the fastest.
Call dplyr package by installing from cran in r
library(dplyr)
(file)$(colname)<-sub("-",NA,file$colname)
It will convert all the blank cell in a particular column as NA
If the column contains "-", "", 0 like this change it in code according to the type of blank cell
E.g. if I get a blank cell like "" instead of "-", then use this code:
(file)$(colname)<-sub("", NA, file$colname)
참고URL : https://stackoverflow.com/questions/24172111/change-the-blank-cells-to-na
'Program Club' 카테고리의 다른 글
| Javascript 변수를 선언 할 때 var가 필요합니까? (0) | 2020.12.07 |
|---|---|
| 파일 시작 부분에 줄 추가 (0) | 2020.12.07 |
| iOS 8에서 NSMutableAttributedString을 사용하는 문자열의 밑줄 부분이 작동하지 않습니다. (0) | 2020.12.06 |
| Nodemon으로 시작 스크립트를 실행하는 방법은 무엇입니까? (0) | 2020.12.06 |
| Eclipse LauncherFactory에 대한 NoClassDefFoundError로 인해 JUnit 5를 사용하여 발견 된 테스트가 없습니다. (0) | 2020.12.06 |