as.numeric
が非数値を に強制するという事実を利用できますNA
。つまり、次のようにしてみてください。
これがあなたのデータです:
temp <- structure(list(age = c(64.3573, 69.9043, 65.6633, 50.3693, 57.0334,
81.4939, 56.954, 76.9298), CALCIUM = c(1.1, 8.1, 8.6, 8.1, 8.7,
1.1, 9.8, 9.1), CREATININE = c(NA, 1.1, 0.8, 1.3, 0.8, NA, 1,
0.8), GLUCOSE = structure(c(5L, 4L, 3L, 2L, 6L, 6L, 1L, 6L), .Label = c("",
"418", "461", "472", "488", "NEG"), class = "factor")), .Names = c("age",
"CALCIUM", "CREATININE", "GLUCOSE"), class = "data.frame", row.names = c(NA,
-8L))
そしてその現在の構造:
str(temp)
# 'data.frame': 8 obs. of 4 variables:
# $ age : num 64.4 69.9 65.7 50.4 57 ...
# $ CALCIUM : num 1.1 8.1 8.6 8.1 8.7 1.1 9.8 9.1
# $ CREATININE: num NA 1.1 0.8 1.3 0.8 NA 1 0.8
# $ GLUCOSE : Factor w/ 6 levels "","418","461",..: 5 4 3 2 6 6 1 6
最後の列を数値に変換しますが、これは因数であるため、最初に文字に変換する必要があります。警告に注意してください。私たちは実際にそれについて満足しています。
temp$GLUCOSE <- as.numeric(as.character(temp$GLUCOSE))
# Warning message:
# NAs introduced by coercion
結果:
temp
# age CALCIUM CREATININE GLUCOSE
# 1 64.3573 1.1 NA 488
# 2 69.9043 8.1 1.1 472
# 3 65.6633 8.6 0.8 461
# 4 50.3693 8.1 1.3 418
# 5 57.0334 8.7 0.8 NA
# 6 81.4939 1.1 NA NA
# 7 56.9540 9.8 1.0 NA
# 8 76.9298 9.1 0.8 NA
楽しみのために、別のアプローチを提供する私がまとめた小さな関数を次に示します。
makemeNA <- function (mydf, NAStrings, fixed = TRUE) {
if (!isTRUE(fixed)) {
mydf[] <- lapply(mydf, function(x) gsub(NAStrings, "", x))
NAStrings <- ""
}
mydf[] <- lapply(mydf, function(x) type.convert(
as.character(x), na.strings = NAStrings))
mydf
}
この関数を使用すると、正規表現を指定して、何を値にするかを識別できNA
ます。私はあまりテストしていないので、正規表現機能は自己責任で使用してください。
上記と同じ「一時」オブジェクトを使用して、これらを試して関数の動作を確認します。
# Change anything that is just text to NA
makemeNA(temp, "[A-Za-z]", fixed = FALSE)
# Change any exact matches with "NEG" to NA
makemeNA(temp, "NEG")
# Change any matches with 3-digit integers to NA
makemeNA(temp, "^[0-9]{3}$", fixed = FALSE)