Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pipe to if statements in R

Tags:

r

magrittr

I have data from my Facebook, Twitter, Instagram, Youtube, and LinkedIn accounts that I'd like to analyze. I have a data frame similar to the following:

df <- data.frame(tw_likes = c(5,4,6,NA,NA,NA,NA,NA,NA), 
                 tw_comments = c(3,5,NA,NA,NA,NA,NA,NA,NA), 
                 fb_likes = c(NA,NA,NA,7,4,8,NA,NA,NA), 
                 fb_comments = c(NA,NA,NA,NA,NA,7,NA,NA,NA), 
                 ig_likes = c(NA,NA,NA,NA,NA,NA,NA,NA,5), 
                 ig_comments = c(NA,NA,NA,NA,NA,NA,43,4,2))

what I want to do is create an additional column Platform that will take the values of "Twitter, "Facebook, or "Instagram" based on the above dataframe.

My tactic has been the following:

for(i in 1:nrow(df){
     if(!is.na(df$tw_likes[i]) | !is.na(df$tw_comments[i])){
          df$Platform[i] <- "Twitter"
     }
     else if(!is.na(df$fb_likes[i]) | !is.na(df$fb_comments[i])){
          df$Platform[i] <- "Facebook"
     }
     else if(!is.na(df$ig_likes[i]) | !is.na(df$ig_comments[i])){
          df$Platform[i] <- "Instagram"
     }
}

This does work, but becomes messier to read. In reality I have more columns and more social media platforms to deal with, so is there a way to pipe the data so I at least don't have to write df$ so many times?

Another thought I had was if I couldn't remove the df$s, could I combine the !is.na() statements to be one statement per if statement?

like image 436
Jacob Avatar asked Jan 28 '26 01:01

Jacob


2 Answers

Here's an option with dplyr's case_when()

df %>% 
  mutate(Plataform = case_when(
    !is.na(tw_likes) | !is.na(tw_comments) ~ "Twitter",
    !is.na(fb_likes) | !is.na(fb_comments) ~ "Facebook",
    !is.na(ig_likes) | !is.na(ig_comments) ~ "Instagram"))
like image 131
Fino Avatar answered Jan 29 '26 15:01

Fino


Here is one way in base R to split the dataset into a list of same prefix columns (by removing the suffix substring from the column names), do a rowSums to create a logical matrix, apply max.col to get the column position for each row and change that index by passing a vector of replacement values in the same order of split column names

i1 <- max.col(sapply(split.default(df, sub("_.*", "", names(df))),
        function(x) rowSums(!is.na(x)) > 0 ), 'first')
df$Platform <- c("Facebook", "Instagram", "Twitter")[i1]
df$Platform
#[1] "Twitter"   "Twitter"   "Twitter"   "Facebook"  "Facebook"  
#[6]   "Facebook"  "Instagram" "Instagram" "Instagram"
like image 24
akrun Avatar answered Jan 29 '26 15:01

akrun



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!