<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/using-mca-and-variable-clustering-in-r-for-insights-in-customer-attrition/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://datascienceplus.com/using-mca-and-variable-clustering-in-r-for-insights-in-customer-attrition/"> DataScience+</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Analytical challenges in multivariate data analysis and predictive modeling include identifying redundant and irrelevant variables. A recommended analytics approach is to first address the redundancy; which can be achieved by identifying groups of variables that are as correlated as possible among themselves and as uncorrelated as possible with other variable groups in the same data set. On the other hand, relevancy is about potential predictor variables and involves understanding the relationship between the target variable and input variables. </p>
<p>Multiple correspondence analysis (MCA) is a multivariate data analysis and data mining tool for finding and constructing a low-dimensional visual representation of variable associations among groups of categorical variables. Variable clustering as a tool for identifying redundancy is often applied to get a first impression of variable associations and multivariate data structure.</p>
<p>The motivations of this post are to illustrate the applications of: 1) preparing input variables for analysis and predictive modeling, 2) MCA as a multivariate exploratory data analysis and categorical data mining tool for business insights of customer churn data, and 3) variable clustering of categorical variables for the identification of redundant variables.</p>
<p><strong>Customer churn data in this analysis: </strong><br>
Customer attrition is a metrics businesses use to monitor and quantify the loss of customers and/or clients for various reasons. The data set includes customer-level demographic, account and services information including monthly charge amounts and length of service with the company. Customers who left the company for competitors (Yes) or staying with the company (No) have been identified in the last column labeled churn. </p>
<p><strong> Load Packages </strong></p>
<pre>
require(caret)
require(plyr)
require(car)
require(dplyr)
require(reshape2)
theme_set(theme_bw(12))
</pre>
<h2> Import and Pre-process Data </h2>
<p>The data set used in this post was obtained from the <a target="_blank" rel="nofollow" href="https://www.ibm.com/communities/analytics/watson-analytics-blog/telco-customer-churn/">watson-analytics-blog</a> site. Click the hyperlink “Watson Analytics Sample Dataset – Telco Customer Churn” to download the file “WA_Fn-UseC_-Telco-Customer-Churn.csv”.</p>
<pre>
setwd(&quot;path to the location  of your copy of the saved csv data file&quot;)

churn &lt;- read.table(&quot;WA_Fn-UseC_-Telco-Customer-Churn,csv&quot;, sep=&quot;,&quot;, header=TRUE)
## inspect data dimensions and structure
str(churn)
<em>## 'data.frame': 7043 obs. of 21 variables:
## $ customerID : Factor w/ 7043 levels &quot;0002-ORFBO&quot;,&quot;0003-MKNFE&quot;,..: 5376 3963 2565 5536 6512 6552 1003 4771 5605 4535 ...
## $ gender : Factor w/ 2 levels &quot;Female&quot;,&quot;Male&quot;: 1 2 2 2 1 1 2 1 1 2 ...
## $ SeniorCitizen : int 0 0 0 0 0 0 0 0 0 0 ...
## $ Partner : Factor w/ 2 levels &quot;No&quot;,&quot;Yes&quot;: 2 1 1 1 1 1 1 1 2 1 ...
## $ Dependents : Factor w/ 2 levels &quot;No&quot;,&quot;Yes&quot;: 1 1 1 1 1 1 2 1 1 2 ...
## $ tenure : int 1 34 2 45 2 8 22 10 28 62 ...
## $ PhoneService : Factor w/ 2 levels &quot;No&quot;,&quot;Yes&quot;: 1 2 2 1 2 2 2 1 2 2 ...
## $ MultipleLines : Factor w/ 3 levels &quot;No&quot;,&quot;No phone service&quot;,..: 2 1 1 2 1 3 3 2 3 1 ...
## $ InternetService : Factor w/ 3 levels &quot;DSL&quot;,&quot;Fiber optic&quot;,..: 1 1 1 1 2 2 2 1 2 1 ...
## $ OnlineSecurity : Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 1 3 3 3 1 1 1 3 1 3 ...
## $ OnlineBackup : Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 3 1 3 1 1 1 3 1 1 3 ...
## $ DeviceProtection: Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 1 3 1 3 1 3 1 1 3 1 ...
## $ TechSupport : Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 1 1 1 3 1 1 1 1 3 1 ...
## $ StreamingTV : Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 1 1 1 1 1 3 3 1 3 1 ...
## $ StreamingMovies : Factor w/ 3 levels &quot;No&quot;,&quot;No internet service&quot;,..: 1 1 1 1 1 3 1 1 3 1 ...
## $ Contract : Factor w/ 3 levels &quot;Month-to-month&quot;,..: 1 2 1 2 1 1 1 1 1 2 ...
## $ PaperlessBilling: Factor w/ 2 levels &quot;No&quot;,&quot;Yes&quot;: 2 1 2 1 2 2 2 1 2 1 ...
## $ PaymentMethod : Factor w/ 4 levels &quot;Bank transfer (automatic)&quot;,..: 3 4 4 1 3 3 2 4 3 1 ...
## $ MonthlyCharges : num 29.9 57 53.9 42.3 70.7 ...
## $ TotalCharges : num 29.9 1889.5 108.2 1840.8 151.7 ...
## $ Churn : Factor w/ 2 levels &quot;No&quot;,&quot;Yes&quot;: 1 1 2 1 2 2 1 1 2 1 </em></pre>
<p>The raw data set contains 7043 records and 21 variables. Looking at the data structure, some data columns need recoding. For instance, changing values from “No phone service” and “No internet service” to “No”, for consistency. The following code statements are to recode those observations and more.</p>
<pre>
## recode selected observations 
churn$MultipleLines &lt;- as.factor(mapvalues(churn$MultipleLines, 
                                           from=c(&quot;No phone service&quot;),
                                           to=c(&quot;No&quot;)))

churn$InternetService &lt;- as.factor(mapvalues(churn$InternetService, 
                                             from=c(&quot;Fiber optic&quot;),
                                             to=c(&quot;Fiberoptic&quot;)))

churn$PaymentMethod &lt;- as.factor(mapvalues(churn$PaymentMethod,
                                           from=c(&quot;Credit card (automatic)&quot;,&quot;Electronic check&quot;,&quot;Mailed check&quot;,
&quot;Bank transfer (automatic)&quot;),
                                           to=c(&quot;Creditcard&quot;,&quot;Electronicheck&quot;,&quot;Mailedcheck&quot;,&quot;Banktransfer&quot;)))

churn$Contract &lt;- as.factor(mapvalues(churn$Contract,
                                      from=c(&quot;Month-to-month&quot;,
                                             &quot;Two year&quot;, &quot;One year&quot;),
                                      to=c(&quot;MtM&quot;,&quot;TwoYr&quot;, &quot;OneYr&quot;)))


cols_recode1 &lt;- c(10:15)
for(i in 1:ncol(churn[,cols_recode1])) {
        churn[,cols_recode1][,i] &lt;- as.factor(mapvalues
                                              (churn[,cols_recode1][,i], from =c(&quot;No internet service&quot;),to=c(&quot;No&quot;)))
}
</pre>
<p>Besides, values in the SeniorCitizen column were entered as 0 and 1. Let’s recode this variable as “No” and “Yes”, respectively, for consistency.</p>
<pre>
churn$SeniorCitizen &lt;- as.factor(mapvalues(churn$SeniorCitizen,
                                      from=c(&quot;0&quot;,&quot;1&quot;),
                                      to=c(&quot;No&quot;, &quot;Yes&quot;)))
</pre>
<p>Exclude the consumer id and total charges columns from data analysis.</p>
<pre>
cols_drop &lt;- c(1, 20)
churn &lt;- churn[,-cols_drop]
</pre>
<p>Let’s do summary statistics of the two numerical variables to see distribution of the data.</p>
<pre>
summary(churn$MonthlyCharges)
<em>## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 18.25 35.50 70.35 64.76 89.85 118.80
</em></pre>
<pre>
summary(churn$tenure)
<em>## Min. 1st Qu. Median Mean 3rd Qu. Max. ## 0.00 9.00 29.00 32.37 55.00 72.00
</em></pre>
<p>On the basis of the data distributions above, values in the tenure and monthly charges numerical columns could be coerced to a 3-level categorical value as follows.</p>
<pre>
churn$tenure &lt;- as.factor(car::recode(churn$tenure, &quot;1:9 = 'ShortTenure'; 
                               9:29 = 'MediumTenure'; else = 'LongTenure'&quot;))

churn$MonthlyCharges &lt;- as.factor(car::recode(churn$MonthlyCharges, &quot;1:35 = 'LowCharge';35:70 = 'MediumCharge'; else = 'HighCharge'&quot;))
</pre>
<p>It’s time to check for missing values in the pre-processed data set.</p>
<pre>
mean(is.na(churn)) 
<em>## [1] 0
</em></pre>
<p>There are no missing values. How about the category levels of each variable?</p>
<pre>
## check for factor levels in each column
nfactors &lt;- apply(churn, 2, function(x) nlevels(as.factor(x))) 
nfactors
<em>## gender SeniorCitizen Partner Dependents ## 2 2 2 2 ## tenure PhoneService MultipleLines InternetService ## 3 2 2 3 ## OnlineSecurity OnlineBackup DeviceProtection TechSupport ## 2 2 2 2 ## StreamingTV StreamingMovies Contract PaperlessBilling ## 2 2 3 2 ## PaymentMethod MonthlyCharges Churn ## 4 3 2
</em></pre>
<p>Now, the data set is ready for analysis.</p>
<h2> Partitioning the raw data into 70% training and 30% testing data sets </h2>
<pre>
inTrain &lt;- createDataPartition(churn$Churn, p=0.7, list=FALSE)
## set random seed to make reproducible results
set.seed(324)
training &lt;- churn[inTrain,]
testing &lt;- churn[-inTrain,]
</pre>
<p>Check for the dimensions of the training and testing data sets</p>
<pre>
dim(training) ; dim(testing)
<em>## [1] 4931 19
## [1] 2112 19
</em></pre>
<p>As expected, the training data set contains 4931 observations and 19 columns, whereas the testing data set contains 2112 observations and 19 columns.</p>
<h2> Multiple Correspondence Analysis (MCA) </h2>
<p>Invoke the FactoMiner &amp; factoextra packages.</p>
<pre>
require(FactoMineR)
require(factoextra)
res.mca &lt;- MCA(training, quali.sup=c(17,19), graph=FALSE)
fviz_mca_var(res.mca, repel=TRUE)
</pre>
<p>Here is the plot of the MCA.<br>
<a title="" data-rel="lightbox-0" target="_blank" rel="nofollow" href="https://i0.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig1_MCA_Plot.png?ssl=1"><img sizes="(max-width: 490px) 100vw, 490px" alt="" class="wp-image-6161" src="https://i0.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig1_MCA_Plot-490x356.png?w=450&ssl=1" data-recalc-dims="1"></a></p>
<p>A general guide to extrapolating from the figure above for business insights would be to observe and make a note as to how close input variables are to the target variable and to each other. For instance, customers with month to month contract, those with fiber optic internet service, senior citizens, customers with high monthly charges, single customers or customers with no dependents, those with paperless billing are being related to a short tenure with the company and a propensity of risk to churn. </p>
<p>On the other hand, customers with 1 – 2 years contract, those with DSL internet service, younger customers, those with low monthly charges, customers with multiple lines, online security and tech support services are being related to a long tenure with the company and a tendency to stay with company. </p>
<h2> Variable Clustering </h2>
<p>Load the ClustOfVar package and the hclustvar function produces a tree of variable groups. A paper detailing the ClustOfVar package is <a target="_blank" rel="nofollow" href="https://arxiv.org/pdf/1112.0295.pdf">here</a></p>
<pre>
require(ClustOfVar)
# run variable clustering excluding the target variable (churn) 
variable_tree &lt;- hclustvar(X.quali = training[,1:18])
#plot the dendrogram of variable groups
plot(variable_tree)
</pre>
<p>Here is a tree of categorical variable groups.<br>
<a title="" data-rel="lightbox-1" target="_blank" rel="nofollow" href="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig2_variable_clustering.png?ssl=1"><img sizes="(max-width: 490px) 100vw, 490px" alt="" class="wp-image-6162" src="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig2_variable_clustering-490x356.png?w=450&ssl=1" data-recalc-dims="1"></a></p>
<p>The dendrogram suggests that the 18 input variables can be combined into approximately 7 – 9 groups of variables. That is one way of going about it. The good news is that the ClusofVar package offers a function to cut the cluster into any number of desired groups (clusters) of variables. So, the syntax below will run 25 bootstrap samples of the trees to produce a plot of stability of variable cluster partitions.</p>
<pre>
# requesting for 25 bootstrap samplings and a plot
stability(variable_tree, B=25) 
</pre>
<p><a title="" data-rel="lightbox-2" target="_blank" rel="nofollow" href="https://i1.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig3_cluster_stability_plot.png?ssl=1"><img sizes="(max-width: 490px) 100vw, 490px" alt="" class="wp-image-6163" src="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig3_cluster_stability_plot-490x356.png?w=450&ssl=1" data-recalc-dims="1"></a><br>
The plot of stability of variable cluster partitions suggests approximately a 7 to 9-cluster solution. The syntax below will list a consensus list of 9-clusters along with the variables names included in each cluster.</p>
<pre>
## cut the variable tree into 9(?) groups of variables 
clus &lt;- cutreevar(variable_tree,9)
## print the list of variables in each cluster groups
print(clus$var)
<em>## $cluster1
## squared loading
## gender 1
## ## $cluster2
## squared loading
## SeniorCitizen 1
## ## $cluster3
## squared loading
## Partner 0.7252539
## Dependents 0.7252539
## ## $cluster4
## squared loading
## tenure 0.7028741
## Contract 0.7162027
## PaymentMethod 0.4614923
## ## $cluster5
## squared loading
## PhoneService 0.6394947
## MultipleLines 0.6394947
## ## $cluster6
## squared loading
## InternetService 0.9662758
## MonthlyCharges 0.9662758
## ## $cluster7
## squared loading
## OnlineSecurity 0.5706136
## OnlineBackup 0.4960295
## TechSupport 0.5801424
## ## $cluster8
## squared loading
## DeviceProtection 0.5319719
## StreamingTV 0.6781781
## StreamingMovies 0.6796616
## ## $cluster9
## squared loading
## PaperlessBilling 1
</em></pre>
<p>The 9-clusters and the variable names in each cluster are listed above. The practical guide to minimizing redundancy is to select a cluster representative. However, subject-matter considerations should have a say in the consideration and selection of other candidate representatives of each variable cluster group. </p>
<h2> Descriptive statistics of customer churn </h2>
<p>what was the overall customer churn rate in the training data set?</p>
<pre>
# overall customer churn rate
round(prop.table(table(training$Churn))*100,1)
<em>## ## No Yes ## 73.5 26.5
</em></pre>
<p>The overall customer attrition rate was approximately 26.5%.<br>
<strong> Customer churn rate by demography, account and service information </strong></p>
<pre>
cols_aggr_demog &lt;- c(1:4,6:7,9:14,16)
variable &lt;- rep(names(training[,cols_aggr_demog]),each=4)
demog_counts=c()
for(i in 1:ncol(training[,cols_aggr_demog])) {
    demog_count &lt;- ddply(training, .(training[,cols_aggr_demog][,i],training$Churn), &quot;nrow&quot;)
     names(demog_count) &lt;- c(&quot;class&quot;,&quot;Churn&quot;,&quot;count&quot;)
    demog_counts &lt;- as.data.frame(rbind(demog_counts, demog_count))
 }

demog_churn_rate &lt;- as.data.frame(cbind(variable, demog_counts))
demog_churn_rate1 &lt;- dcast(demog_churn_rate, variable + class ~ Churn, value.var=&quot;count&quot;)
demog_churn_rate2 &lt;- mutate(demog_churn_rate1, churn_rate=round((Yes/(No+Yes)*100)-26.5,1))
demog &lt;- as.data.frame(paste(demog_churn_rate2$variable,demog_churn_rate2$class))
names(demog) &lt;- c(&quot;Category&quot;)
demog2 &lt;- as.data.frame(cbind(demog,demog_churn_rate2))
cols_aggr_nlev3 &lt;- c(5,8,15,18)
variable &lt;- rep(names(training[,cols_aggr_nlev3]),each=6)
nlev3_counts=c()
for(i in 1:ncol(training[,cols_aggr_nlev3])) {
    nlev3_count &lt;- ddply(training, .(training[,cols_aggr_nlev3][,i],training$Churn), &quot;nrow&quot;)
     names(nlev3_count) &lt;- c(&quot;class&quot;,&quot;Churn&quot;,&quot;count&quot;)
    nlev3_counts &lt;- as.data.frame(rbind(nlev3_counts, nlev3_count))
 }

nlev3_churn_rate &lt;- as.data.frame(cbind(variable, nlev3_counts))
nlev3_churn_rate1 &lt;- dcast(nlev3_churn_rate, variable + class ~ Churn, value.var=&quot;count&quot;)
nlev3_churn_rate2 &lt;- mutate(nlev3_churn_rate1, churn_rate=round((Yes/(No+Yes)*100)-26.5,1))
nlev3 &lt;- as.data.frame(paste(nlev3_churn_rate2$variable,nlev3_churn_rate2$class))
names(nlev3) &lt;- c(&quot;Category&quot;)
nlev3 &lt;- as.data.frame(cbind(nlev3,nlev3_churn_rate2))
variable &lt;- rep(&quot;PaymentMethod&quot;,8)
nlev4_count &lt;- ddply(training, .(training[,17],training$Churn), &quot;nrow&quot;)
names(nlev4_count) &lt;- c(&quot;class&quot;,&quot;Churn&quot;,&quot;count&quot;)
nlev4_churn_rate &lt;- as.data.frame(cbind(variable, nlev4_count))
nlev4_churn_rate1 &lt;- dcast(nlev4_churn_rate, variable + class ~ Churn, value.var=&quot;count&quot;)
nlev4_churn_rate2 &lt;- mutate(nlev4_churn_rate1, churn_rate=round((Yes/(No+Yes)*100)-26.5,1))
nlev4 &lt;- as.data.frame(paste(nlev4_churn_rate$variable4,nlev4_churn_rate2$class))
names(nlev4) &lt;- c(&quot;Category&quot;)
nlev4 &lt;- as.data.frame(cbind(nlev4,nlev4_churn_rate2))
final_agg &lt;- as.data.frame(rbind(demog2, nlev3, nlev4))

ggplot(final_agg, aes(Category, churn_rate, color=churn_rate &lt; 0)) +
    geom_segment(aes(x=reorder(Category, -churn_rate), xend = Category,
                     y = 0, yend = churn_rate), 
                 size = 1.1, alpha = 0.7) +
    geom_point(size = 2.5) +
        theme(legend.position=&quot;none&quot;) +
    xlab(&quot;Variable&quot;) +
    ylab(&quot;Customer Churn (%)&quot;) +
    ggtitle(&quot;Customer Attrition rate \n Difference from the overall average (%)&quot;) +
    theme(axis.text.x=element_text(angle=45, hjust=1)) +
    coord_flip()
</pre>
<p><a title="" data-rel="lightbox-3" target="_blank" rel="nofollow" href="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig4_Descriptive_plot.png?ssl=1"><img sizes="(max-width: 490px) 100vw, 490px" alt="" class="wp-image-6164" src="https://i2.wp.com/datascienceplus.com/wp-content/uploads/2017/04/Fig4_Descriptive_plot-490x356.png?w=450&ssl=1" data-recalc-dims="1"></a></p>
<p>Looking at the figure above, customers with higher than average attrition rates include those with an electronic check, with month to month contracts, with higher monthly charges and paperless billing. On a positive note, customers with low monthly charges, longer period contract, with online security services, with dependents or with partners, those paying with credit card or bank transfer showed a much lower than average rates of attrition. </p>
<h2> In conclusion </h2>
<p>Variables such as contract length, bill payment method, internet service type and even customer demography appeared to play a role in customer attrition and retention. The next step for this company would be to deploy predictive and prescriptive models that would score prospective customers for the propensity of risk to churn. Hope this post is helpful. Please leave your comments or suggestions below. Ok to networking with the author on <a target="_blank" rel="nofollow" href="https://www.linkedin.com/in/mesfin-gebeyaw-00800867/">LinkedIn</a>.</p>
<ul></ul>
<p><strong>
<p>Related Post</p>
<p>
<ol>
<li><a title="Permanent Link toWeb Scraping and Applied Clustering Global Happiness and Social Progress Index" target="_blank" rel="nofollow" href="https://datascienceplus.com/web-scraping-and-applied-clustering-global-happiness-and-social-progress-index/">Web Scraping and Applied Clustering Global Happiness and Social Progress Index</a></li>
<li><a title="Permanent Link toKey Phrase Extraction from Tweets" target="_blank" rel="nofollow" href="https://datascienceplus.com/key-phrase-extraction-from-tweets/">Key Phrase Extraction from Tweets</a></li>
<li><a title="Permanent Link toFinancial time series forecasting – an easy approach" target="_blank" rel="nofollow" href="https://datascienceplus.com/financial-time-series-forecasting-an-easy-approach/">Financial time series forecasting – an easy approach</a></li>
<li><a title="Permanent Link toOutlier detection and treatment with R" target="_blank" rel="nofollow" href="https://datascienceplus.com/outlier-detection-and-treatment-with-r/">Outlier detection and treatment with R</a></li>
<li><a title="Permanent Link toImplementing Apriori Algorithm in R" target="_blank" rel="nofollow" href="https://datascienceplus.com/implementing-apriori-algorithm-in-r/">Implementing Apriori Algorithm in R</a></li>
</ol></strong>
<div>
<a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=lAeRPu9DqCU:YmFqtXe-6wE:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/datascienceplus?i=lAeRPu9DqCU:YmFqtXe-6wE:D7DqB2pKExk" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=lAeRPu9DqCU:YmFqtXe-6wE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=qj6IDK7rITs" border="0"></a> <a target="_blank" rel="nofollow" href="http://feeds.feedburner.com/~ff/datascienceplus?a=lAeRPu9DqCU:YmFqtXe-6wE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/datascienceplus?d=yIl2AUoC8zA" border="0"></a>
</div>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="https://datascienceplus.com/using-mca-and-variable-clustering-in-r-for-insights-in-customer-attrition/"> DataScience+</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/uCoa-RYC_oQ"></a></div>