मेरे पास एक डेटा फ्रेम है और कुछ कॉलम में NA
मान हैं।
मैं इन NA
मानों को शून्य से कैसे बदलूँ?
मेरे पास एक डेटा फ्रेम है और कुछ कॉलम में NA
मान हैं।
मैं इन NA
मानों को शून्य से कैसे बदलूँ?
जवाबों:
मेरी टिप्पणी @ gsk3 उत्तर में देखें। एक सरल उदाहरण:
> m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
> d <- as.data.frame(m)
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 4 3 NA 3 7 6 6 10 6 5
2 9 8 9 5 10 NA 2 1 7 2
3 1 1 6 3 6 NA 1 4 1 6
4 NA 4 NA 7 10 2 NA 4 1 8
5 1 2 4 NA 2 6 2 6 7 4
6 NA 3 NA NA 10 2 1 10 8 4
7 4 4 9 10 9 8 9 4 10 NA
8 5 8 3 2 1 4 5 9 4 7
9 3 9 10 1 9 9 10 5 3 3
10 4 2 2 5 NA 9 7 2 5 5
> d[is.na(d)] <- 0
> d
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 4 3 0 3 7 6 6 10 6 5
2 9 8 9 5 10 0 2 1 7 2
3 1 1 6 3 6 0 1 4 1 6
4 0 4 0 7 10 2 0 4 1 8
5 1 2 4 0 2 6 2 6 7 4
6 0 3 0 0 10 2 1 10 8 4
7 4 4 9 10 9 8 9 4 10 0
8 5 8 3 2 1 4 5 9 4 7
9 3 9 10 1 9 9 10 5 3 3
10 4 2 2 5 0 9 7 2 5 5
आवेदन करने की कोई आवश्यकता नहीं है apply
। =)
संपादित करें
आपको norm
पैकेज पर भी ध्यान देना चाहिए । लापता डेटा विश्लेषण के लिए इसमें बहुत सारी अच्छी विशेषताएं हैं। =)
df[19:28][is.na(df[19:28])] <- 0
Dplyr संकरित विकल्प अब बेस आर सबसेट रीसाइनस की तुलना में लगभग 30% तेज हैं। 100M डेटापॉइंट डेटाफ्रेम mutate_all(~replace(., is.na(.), 0))
पर बेस आर d[is.na(d)] <- 0
विकल्प की तुलना में आधा सेकंड तेजी से चलता है । एक विशेष रूप से एक ifelse()
या एक से बचने के लिए क्या चाहता है if_else()
। (इन दृष्टिकोणों को शामिल करने के कारण पूरा 600 परीक्षण विश्लेषण 4.5 घंटे तक चला।) कृपया पूर्ण परिणामों के लिए नीचे दिए गए बेंचमार्क विश्लेषण देखें।
यदि आप बड़े पैमाने पर डेटाफ़्रेम से जूझ रहे हैं, data.table
तो सभी का सबसे तेज़ विकल्प है: मानक बेस आर दृष्टिकोण की तुलना में 40% तेज । यह जगह में डेटा को संशोधित करता है, प्रभावी रूप से आपको लगभग दो बार काम करने की अनुमति देता है जितना एक बार में डेटा।
Locationally:
mutate_at(c(5:10), ~replace(., is.na(.), 0))
mutate_at(vars(var5:var10), ~replace(., is.na(.), 0))
mutate_at(vars(contains("1")), ~replace(., is.na(.), 0))
contains()
कोशिश के स्थान पर ends_with()
,starts_with()
mutate_at(vars(matches("\\d{2}")), ~replace(., is.na(.), 0))
सशर्त रूप से:
(केवल एकल प्रकार बदलें और अन्य प्रकारों को अकेला छोड़ दें।)
mutate_if(is.integer, ~replace(., is.na(.), 0))
mutate_if(is.numeric, ~replace(., is.na(.), 0))
mutate_if(is.character, ~replace(., is.na(.), 0))
Dplyr 0.8.0 के लिए अपडेट किया गया: फ़ंक्शन purrr प्रारूप ~
प्रतीकों का उपयोग करते हैं : पदावनत funs()
तर्कों को प्रतिस्थापित करना ।
# Base R:
baseR.sbst.rssgn <- function(x) { x[is.na(x)] <- 0; x }
baseR.replace <- function(x) { replace(x, is.na(x), 0) }
baseR.for <- function(x) { for(j in 1:ncol(x))
x[[j]][is.na(x[[j]])] = 0 }
# tidyverse
## dplyr
dplyr_if_else <- function(x) { mutate_all(x, ~if_else(is.na(.), 0, .)) }
dplyr_coalesce <- function(x) { mutate_all(x, ~coalesce(., 0)) }
## tidyr
tidyr_replace_na <- function(x) { replace_na(x, as.list(setNames(rep(0, 10), as.list(c(paste0("var", 1:10)))))) }
## hybrid
hybrd.ifelse <- function(x) { mutate_all(x, ~ifelse(is.na(.), 0, .)) }
hybrd.replace_na <- function(x) { mutate_all(x, ~replace_na(., 0)) }
hybrd.replace <- function(x) { mutate_all(x, ~replace(., is.na(.), 0)) }
hybrd.rplc_at.idx<- function(x) { mutate_at(x, c(1:10), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.nse<- function(x) { mutate_at(x, vars(var1:var10), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.stw<- function(x) { mutate_at(x, vars(starts_with("var")), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.ctn<- function(x) { mutate_at(x, vars(contains("var")), ~replace(., is.na(.), 0)) }
hybrd.rplc_at.mtc<- function(x) { mutate_at(x, vars(matches("\\d+")), ~replace(., is.na(.), 0)) }
hybrd.rplc_if <- function(x) { mutate_if(x, is.numeric, ~replace(., is.na(.), 0)) }
# data.table
library(data.table)
DT.for.set.nms <- function(x) { for (j in names(x))
set(x,which(is.na(x[[j]])),j,0) }
DT.for.set.sqln <- function(x) { for (j in seq_len(ncol(x)))
set(x,which(is.na(x[[j]])),j,0) }
DT.nafill <- function(x) { nafill(df, fill=0)}
DT.setnafill <- function(x) { setnafill(df, fill=0)}
library(microbenchmark)
# 20% NA filled dataframe of 10 Million rows and 10 columns
set.seed(42) # to recreate the exact dataframe
dfN <- as.data.frame(matrix(sample(c(NA, as.numeric(1:4)), 1e7*10, replace = TRUE),
dimnames = list(NULL, paste0("var", 1:10)),
ncol = 10))
# Running 600 trials with each replacement method
# (the functions are excecuted locally - so that the original dataframe remains unmodified in all cases)
perf_results <- microbenchmark(
hybrid.ifelse = hybrid.ifelse(copy(dfN)),
dplyr_if_else = dplyr_if_else(copy(dfN)),
hybrd.replace_na = hybrd.replace_na(copy(dfN)),
baseR.sbst.rssgn = baseR.sbst.rssgn(copy(dfN)),
baseR.replace = baseR.replace(copy(dfN)),
dplyr_coalesce = dplyr_coalesce(copy(dfN)),
tidyr_replace_na = tidyr_replace_na(copy(dfN)),
hybrd.replace = hybrd.replace(copy(dfN)),
hybrd.rplc_at.ctn= hybrd.rplc_at.ctn(copy(dfN)),
hybrd.rplc_at.nse= hybrd.rplc_at.nse(copy(dfN)),
baseR.for = baseR.for(copy(dfN)),
hybrd.rplc_at.idx= hybrd.rplc_at.idx(copy(dfN)),
DT.for.set.nms = DT.for.set.nms(copy(dfN)),
DT.for.set.sqln = DT.for.set.sqln(copy(dfN)),
times = 600L
)
> print(perf_results) Unit: milliseconds expr min lq mean median uq max neval hybrd.ifelse 6171.0439 6339.7046 6425.221 6407.397 6496.992 7052.851 600 dplyr_if_else 3737.4954 3877.0983 3953.857 3946.024 4023.301 4539.428 600 hybrd.replace_na 1497.8653 1706.1119 1748.464 1745.282 1789.804 2127.166 600 baseR.sbst.rssgn 1480.5098 1686.1581 1730.006 1728.477 1772.951 2010.215 600 baseR.replace 1457.4016 1681.5583 1725.481 1722.069 1766.916 2089.627 600 dplyr_coalesce 1227.6150 1483.3520 1524.245 1519.454 1561.488 1996.859 600 tidyr_replace_na 1248.3292 1473.1707 1521.889 1520.108 1570.382 1995.768 600 hybrd.replace 913.1865 1197.3133 1233.336 1238.747 1276.141 1438.646 600 hybrd.rplc_at.ctn 916.9339 1192.9885 1224.733 1227.628 1268.644 1466.085 600 hybrd.rplc_at.nse 919.0270 1191.0541 1228.749 1228.635 1275.103 2882.040 600 baseR.for 869.3169 1180.8311 1216.958 1224.407 1264.737 1459.726 600 hybrd.rplc_at.idx 839.8915 1189.7465 1223.326 1228.329 1266.375 1565.794 600 DT.for.set.nms 761.6086 915.8166 1015.457 1001.772 1106.315 1363.044 600 DT.for.set.sqln 787.3535 918.8733 1017.812 1002.042 1122.474 1321.860 600
ggplot(perf_results, aes(x=expr, y=time/10^9)) +
geom_boxplot() +
xlab('Expression') +
ylab('Elapsed Time (Seconds)') +
scale_y_continuous(breaks = seq(0,7,1)) +
coord_flip()
qplot(y=time/10^9, data=perf_results, colour=expr) +
labs(y = "log10 Scaled Elapsed Time per Trial (secs)", x = "Trial Number") +
coord_cartesian(ylim = c(0.75, 7.5)) +
scale_y_log10(breaks=c(0.75, 0.875, 1, 1.25, 1.5, 1.75, seq(2, 7.5)))
जब डेटासेट बड़ा मिलता है, Tidyr 'के replace_na
ऐतिहासिक दृष्टि से सामने बाहर निकाला था। के माध्यम से चलाने के लिए 100M डेटा बिंदुओं के वर्तमान संग्रह के साथ, यह लगभग पूरी तरह से और साथ ही बेस आर फॉर लूप का प्रदर्शन करता है । मैं यह देखने के लिए उत्सुक हूं कि विभिन्न आकार के डेटाफ्रेम के लिए क्या होता है।
के लिए अतिरिक्त उदाहरण mutate
और summarize
_at
और _all
समारोह वेरिएंट यहां पाया जा सकता: https://rdrr.io/cran/dplyr/man/summarise_all.html
: इसके अतिरिक्त, मैं उपयोगी प्रदर्शनों और उदाहरण के संग्रह यहां पाया https: //blog.exploratory। कब / dplyr-0-5-है-भयानक-यहाँ-क्यों-be095fd4eb8a
विशेष धन्यवाद के साथ:
local()
, और फ्रैंक के रोगी की मदद के बारे में भी समझने में मदद करता है, मूक बलात्कार जो इन दृष्टिकोणों में से कई को गति देने में भूमिका निभाता है। coalesce()
फ़ंक्शन को जोड़ने और विश्लेषण को अद्यतन करने के लिए प्रहार के लिए आर्थुरिप ।data.table
अच्छी तरह से कार्यों को अंजाम देने के लिए ग्रेगर आखिरकार उन्हें लाइनअप में शामिल कर लेता है।is.numeric()
वास्तव में परीक्षण करता है , यह समझाने के लिए ।(बेशक, कृपया ऊपर पहुंचें और उन्हें अपवोट दें, भले ही आप उन दृष्टिकोणों को उपयोगी पाते हों।)
न्यूमेरिक्स के मेरे उपयोग पर ध्यान दें: यदि आपके पास शुद्ध पूर्णांक डेटासेट है, तो आपके सभी कार्य तेजी से चलेंगे। अधिक जानकारी के लिएकृपया alexiz_laz का काम देखें। IRL, मैं 10-15% से अधिक पूर्णांक वाले डेटा सेट का सामना करना याद नहीं कर सकता, इसलिए मैं पूरी तरह से संख्यात्मक डेटाफ़्रेम पर इन परीक्षणों को चला रहा हूं।
हार्डवेयर में 24 जीबी रैम के साथ 3.9 गीगाहर्ट्ज़ सीपीयू का इस्तेमाल किया गया है
df1[j][is.na(df1[j])] = 0
गलत है, होना चाहिएdf1[[j]][is.na(df1[[j]])] = 0
forLp_Sbst
यह किसी को भी ऐसा नहीं लगता है कि किसी को इस पर विचार करने पर विचार करना चाहिएforLp_smplfSbst
coalesce()
विकल्प को हर समय और फिर से जोड़ा है । अपडेट करने के लिए धन्यवाद के लिए धन्यवाद।
एकल वेक्टर के लिए:
x <- c(1,2,NA,4,5)
x[is.na(x)] <- 0
डेटा.फ्रेम के लिए, ऊपर से एक फ़ंक्शन बनाएं, फिर apply
इसे कॉलम पर।
एक प्रतिलिपि प्रस्तुत करने योग्य उदाहरण अगली बार के रूप में यहाँ विस्तृत प्रदान करें:
कैसे एक महान आर प्रतिलिपि प्रस्तुत करने योग्य उदाहरण बनाने के लिए?
is.na
सामान्य कार्य है, और इसमें data.frame
कक्षा की वस्तुओं के लिए विधियाँ हैं । तो यह भी काम करेगा data.frame
!
methods(is.na)
पहली बार भागा , तो मैं वाहा था ? । मुझे पसंद है जब सामान ऐसा होता है! =)
मुझे पता है कि प्रश्न पहले से ही उत्तर दिया गया है, लेकिन इस तरह से करना कुछ के लिए अधिक उपयोगी हो सकता है:
इस फ़ंक्शन को परिभाषित करें:
na.zero <- function (x) {
x[is.na(x)] <- 0
return(x)
}
अब जब भी आपको एनए को वेक्टर में बदलने की आवश्यकता हो तो आप कर सकते हैं:
na.zero(some.vector)
dplyr
0.5.0 के साथ , आप coalesce
फ़ंक्शन का उपयोग कर सकते हैं जिसे आसानी से %>%
पाइप लाइन में एकीकृत किया जा सकता है coalesce(vec, 0)
। यह सभी NA vec
को 0 से बदल देता है :
कहो कि हमारे पास एक डेटा फ्रेम है NA
:
library(dplyr)
df <- data.frame(v = c(1, 2, 3, NA, 5, 6, 8))
df
# v
# 1 1
# 2 2
# 3 3
# 4 NA
# 5 5
# 6 6
# 7 8
df %>% mutate(v = coalesce(v, 0))
# v
# 1 1
# 2 2
# 3 3
# 4 0
# 5 5
# 6 6
# 7 8
replace()
बदलने के NA
लिए मैट्रिक्स या वेक्टर में उपयोग करने का अधिक सामान्य दृष्टिकोण0
उदाहरण के लिए:
> x <- c(1,2,NA,NA,1,1)
> x1 <- replace(x,is.na(x),0)
> x1
[1] 1 2 0 0 1 1
यह भी उपयोग करने के लिए एक विकल्प ifelse()
हैdplyr
df = data.frame(col = c(1,2,NA,NA,1,1))
df <- df %>%
mutate(col = replace(col,is.na(col),0))
levels(A$x) <- append(levels(A$x), "notAnswered") A$x <- replace(A$x,which(is.na(A$x)),"notAnswered")
which
यहां जरूरत नहीं है, आप उपयोग कर सकते हैं x1 <- replace(x,is.na(x),1)
।
NA
करने के लिए 0
एक बड़े डेटा फ्रेम में सिर्फ एक विशिष्ट स्तंभ में हैं और इस समारोह replace()
सबसे प्रभावी ढंग से करते हुए भी सबसे बस काम किया।
यदि आप कारक चर में NA को बदलना चाहते हैं, तो यह उपयोगी हो सकता है:
n <- length(levels(data.vector))+1
data.vector <- as.numeric(data.vector)
data.vector[is.na(data.vector)] <- n
data.vector <- as.factor(data.vector)
levels(data.vector) <- c("level1","level2",...,"leveln", "NAlevel")
यह एक कारक-वेक्टर को एक संख्यात्मक वेक्टर में बदल देता है और एक अन्य कृत्रिम संख्यात्मक कारक स्तर जोड़ता है, जिसे फिर आपकी पसंद के एक अतिरिक्त "एनए-स्तर" के साथ एक कारक-वेक्टर में बदल दिया जाता है।
@ Ianmunoz की पोस्ट पर टिप्पणी की होगी, लेकिन मेरे पास पर्याप्त प्रतिष्ठा नहीं है। आप को जोड़ सकते हैं dplyr
'एस mutate_each
और replace
की देखभाल करने के NA
लिए 0
प्रतिस्थापन। @ AL3xa के उत्तर से डेटाफ्रेम का उपयोग ...
> m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
> d <- as.data.frame(m)
> d
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 4 8 1 9 6 9 NA 8 9 8
2 8 3 6 8 2 1 NA NA 6 3
3 6 6 3 NA 2 NA NA 5 7 7
4 10 6 1 1 7 9 1 10 3 10
5 10 6 7 10 10 3 2 5 4 6
6 2 4 1 5 7 NA NA 8 4 4
7 7 2 3 1 4 10 NA 8 7 7
8 9 5 8 10 5 3 5 8 3 2
9 9 1 8 7 6 5 NA NA 6 7
10 6 10 8 7 1 1 2 2 5 7
> d %>% mutate_each( funs_( interp( ~replace(., is.na(.),0) ) ) )
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1 4 8 1 9 6 9 0 8 9 8
2 8 3 6 8 2 1 0 0 6 3
3 6 6 3 0 2 0 0 5 7 7
4 10 6 1 1 7 9 1 10 3 10
5 10 6 7 10 10 3 2 5 4 6
6 2 4 1 5 7 0 0 8 4 4
7 7 2 3 1 4 10 0 8 7 7
8 9 5 8 10 5 3 5 8 3 2
9 9 1 8 7 6 5 0 0 6 7
10 6 10 8 7 1 1 2 2 5 7
हम यहां मानक मूल्यांकन (एसई) का उपयोग कर रहे हैं, यही कारण है कि हमें "" पर अंडरस्कोर की आवश्यकता है funs_
। हम यह भी उपयोग करने lazyeval
की interp
/ ~
और .
संदर्भ, यानी डेटा फ्रेम "सब कुछ हम साथ काम कर रहे"। अब शून्य हैं!
आप उपयोग कर सकते हैं replace()
उदाहरण के लिए:
> x <- c(-1,0,1,0,NA,0,1,1)
> x1 <- replace(x,5,1)
> x1
[1] -1 0 1 0 1 0 1 1
> x1 <- replace(x,5,mean(x,na.rm=T))
> x1
[1] -1.00 0.00 1.00 0.00 0.29 0.00 1.00 1.00
NA
अपने वेक्टर में एस के सूचकांक को जानते हैं । यह आपके उदाहरण के रूप में छोटे वैक्टर के लिए ठीक है।
x1 <- replace(x,is.na(x),1)
सूचकांक मूल्यों को स्पष्ट रूप से सूचीबद्ध किए बिना काम करेगा।
विधि के dplyr
साथ एक और पाइप संगत विकल्प जो कई स्तंभों के लिए काम करता है:tidyr
replace_na
require(dplyr)
require(tidyr)
m <- matrix(sample(c(NA, 1:10), 100, replace = TRUE), 10)
d <- as.data.frame(m)
myList <- setNames(lapply(vector("list", ncol(d)), function(x) x <- 0), names(d))
df <- d %>% replace_na(myList)
आप उदाहरण के लिए संख्यात्मक कॉलम तक आसानी से प्रतिबंधित कर सकते हैं:
d$str <- c("string", NA)
myList <- myList[sapply(d, is.numeric)]
df <- d %>% replace_na(myList)
उस उद्देश्य के लिए समर्पित फ़ंक्शन ( nafill
/ setnafill
) हाल के data.table
संस्करण में है
install.packages("data.table", repos="https://Rdatatable.gitlab.io/data.table")
library(data.table)
ans_df = nafill(df, fill=0)
setnafill(df, fill=0) # this one updates in-place
एक डेटाफ़्रेम में सभी एनए को बदलने के लिए आप उपयोग कर सकते हैं:
df %>% replace(is.na(.), 0)