Home > OS >  Apply() or forloop for repeating multiple functions when creating new columns in data frame
Apply() or forloop for repeating multiple functions when creating new columns in data frame

Time:07-29

I want to repeat the following code for every species (represented in "veg" character string) so that I have new columns for each species. Right now, I have code for a single species (see below).

  1. I'm sure there is a better tidyverse way to write this initial code but I'm not well-versed in it yet, so suggestions are welcome!
  2. Would I be looking for an apply() function or writing a for-loop to accomplish what I'm trying to do here? Thanks!
#character string of all species I need to operate on:

veg <- c("HECO", "DA_PSSP", "DA_HECO", "DA_PASM", "PSSP", "DA_BOGR", "ACHY", "red_stem_grass", "ELEL?", "ELEL", "BOGR", "DA_ACHY", "ELTR?", "SD_PASM", "not_HECO", "DA_ELEL", "PASM", "ARPU", "big_ligule_bunchgrass", "SD_PERENGRASS", "OPPO", "SD_FORB", "Unk_Parsley", "PHHO", "SD_Unk_Borage", "TAOF", "lupine", "Unk_Borage", "bur_forb", "SD_OPPO", "DA_OPPO", "lithospermum", "SPMU?", "VUOC", "PLPA", "DA_PLPA", "BRTE", "SD_BRTE", "SD_POBU", "AGCR", "POBU", "ALDE", "ERCI", "SD_ERCI", "SD_PIG", "SATR?", "SD_ALDE", "AF01", "DA_ALDE", "COAR", "DA_ATCA", "SD_ARTR", "DA_CHVI", "ARTR", "SD_CHVI", "SD_SHRUB", "CHVI", "SPMU/CO", "DCR")
#example data frame to work with

lpi <- data.frame(transectID = c("a", "a", "a", "b", "b", "b", "c", "c", "c"),
top_layer = c("HECO", 0, "HECO", 0, 0, "PLPA", 0, "ACHY", 0),
lower1 = c("AGCR", 0, "DA_ACHY", 0, 0, "PSSP", 0, "POBU", 0),
lower2 = c(0, 0, 0, 0, 0, 0, 0, 0, 0),
lower3 = c(0, 0, 0, 0, 0, 0, 0, 0, 0))

#create column of presence/absence of the "veg" character string across all layers.

HECO_presence <- data.frame(lpi$top_layer %in% "HECO") #create data frame that I'll populate with columns of presence/absence of veg for each layer. this first line looks at the top layer and assigns each row as true/false depending on if "HECO" is in each row
names(HECO_presence) = "top_layer" #rename the column
HECO_presence$lower1 <- lpi$lower1 %in% "HECO" #new column for presence/absence in lower1 layer
HECO_presence$lower2 <- lpi$lower2 %in% "HECO" #new column for presence/absence in lower2 layer
HECO_presence$lower3 <- lpi$lower3 %in% "HECO" #new column for presence/absence in lower3 layer
HECO_presence$soil_surface <- lpi$soil_surface %in% "HECO" #new column for presence/absence in soil_surface layer

lpi$HECO_presence <- apply(HECO_presence, 1, sum) > 0 #create new column in lpi data frame that assigns a TRUE to each row if the sum of the HECO_presence data frame columns are greater than 0 (i.e. there is at least one veg hit in a row) and FALSE otherwise


HECOhits_transect <- lpi %>%
  group_by(TransectID) %>%
  summarize(HECOhits_transect = sum(HECO_presence))

#join those sums with the lpi dataframe
lpi <- full_join(lpi, HECOhits_transect)

CodePudding user response:

I think something like this is what you are after:

library(tidyverse)

veg <- c("HECO", "DA_PSSP", "DA_HECO", "DA_PASM", "PSSP", "DA_BOGR", "ACHY", "red_stem_grass", "ELEL?", "ELEL", "BOGR", "DA_ACHY", "ELTR?", "SD_PASM", "not_HECO", "DA_ELEL", "PASM", "ARPU", "big_ligule_bunchgrass", "SD_PERENGRASS", "OPPO", "SD_FORB", "Unk_Parsley", "PHHO", "SD_Unk_Borage", "TAOF", "lupine", "Unk_Borage", "bur_forb", "SD_OPPO", "DA_OPPO", "lithospermum", "SPMU?", "VUOC", "PLPA", "DA_PLPA", "BRTE", "SD_BRTE", "SD_POBU", "AGCR", "POBU", "ALDE", "ERCI", "SD_ERCI", "SD_PIG", "SATR?", "SD_ALDE", "AF01", "DA_ALDE", "COAR", "DA_ATCA", "SD_ARTR", "DA_CHVI", "ARTR", "SD_CHVI", "SD_SHRUB", "CHVI", "SPMU/CO", "DCR")


lpi <- data.frame(transectID = c("a", "a", "a", "b", "b", "b", "c", "c", "c"),
                  top_layer = c("HECO", 0, "HECO", 0, 0, "PLPA", 0, "ACHY", 0),
                  lower1 = c("AGCR", 0, "DA_ACHY", 0, 0, "PSSP", 0, "POBU", 0),
                  lower2 = c(0, 0, 0, 0, 0, 0, 0, 0, 0),
                  lower3 = c(0, 0, 0, 0, 0, 0, 0, 0, 0))



for(i in 1:length(veg)){
  
presence <- data.frame(lpi$top_layer %in% veg[i]) #create data frame that I'll populate with columns of presence/absence of veg for each layer. this first line looks at the top layer and assigns each row as true/false depending on if "HECO" is in each row
names(presence) = "top_layer" #rename the column
presence$lower1 <- lpi$lower1 %in% veg[i] #new column for presence/absence in lower1 layer
presence$lower2 <- lpi$lower2 %in% veg[i] #new column for presence/absence in lower2 layer
presence$lower3 <- lpi$lower3 %in% veg[i] #new column for presence/absence in lower3 layer

lpi$presence <- apply(presence, 1, sum) > 0 #create new column in lpi data frame that assigns a TRUE to each row if the sum of the HECO_presence data frame columns are greater than 0 (i.e. there is at least one veg hit in a row) and FALSE otherwise


hits_transect <- lpi %>%
  group_by(transectID) %>%
  summarize(hits_transect = sum(presence))

names(hits_transect)[2] <- paste0(veg[i]," hits")

#join those sums with the lpi dataframe
lpi <<- full_join(lpi, hits_transect)

}

lpi <- lpi %>% select(-presence)

although I had to remove this line


HECO_presence$soil_surface <- lpi$soil_surface %in% "HECO" #new column for presence/absence in soil_surface layer

as it was not a column in the lpi dataframe, but if you can reconcile that it will just be


presence$soil_surface <- lpi$soil_surface %in% veg[i] #new column for presence/absence in soil_surface layer


Hope this is useful, let me know if not :)

  • Related