简体   繁体   中英

R - How to replicate and alter a dataframe based on a list of matching names using a loop

I have a data frame which consists of various species, and a column showing their presence (detection column). I want to end up with a list of data frames, one for each species. Within each species new data frame I want the matching species detection values be turned to a '1', while keeping all other species detection values as 0. Here is an example data frame with two species:

structure(list(Camera.Trap.Name = c("CT-Tst-1-1", "CT-Tst-2-1", 
"CT-Tst-2-1", "CT-Tst-2-1", "CT-Tst-2-1", "CT-Tst-2-1", "CT-Tst-2-1", 
"CT-Tst-2-1", "CT-Tst-3-1", "CT-Tst-3-1", "CT-Tst-3-1", "CT-Tst-3-1", 
"CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", 
"CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", 
"CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", 
"CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-5-1", 
"CT-Tst-5-1", "CT-Tst-5-1", "CT-Tst-8-1", "CT-Tst-8-1", "CT-Tst-8-1", 
"CT-Tst-8-1", "CT-Tst-8-1", "CT-Tst-8-1", "CT-Tst-8-1", "CT-Tst-8-1", 
"CT-Tst-8-1", "CT-Tst-9-1", "CT-Tst-9-1", "CT-Tst-9-1"), Sampling.Event = c("Olney 1", 
"Olney 2", "Olney 2", "Olney 2", "Olney 2", "Olney 2", "Olney 2", 
"Olney 2", "Olney 3", "Olney 3", "Olney 3", "Olney 3", "Olney 5", 
"Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", 
"Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", 
"Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", "Olney 5", 
"Olney 7", "Olney 7", "Olney 7", "Olney 7", "Olney 7", "Olney 7", 
"Olney 7", "Olney 7", "Olney 7", "Olney 7", "Olney 7", "Olney 7", 
"Olney 5", "Olney 5", "Olney 5"), Photo.Date = c("2018-03-28", 
"2018-04-20", "2018-05-02", "2018-05-07", "2018-05-09", "2018-05-10", 
"2018-05-11", "2018-05-15", "2019-11-13", "2019-11-14", "2019-11-15", 
"2019-11-16", "2020-03-24", "2020-03-25", "2020-03-26", "2020-03-31", 
"2020-04-01", "2020-04-02", "2020-04-03", "2020-04-04", "2020-04-04", 
"2020-04-05", "2020-04-06", "2020-04-06", "2020-04-07", "2020-04-07", 
"2020-04-08", "2020-04-09", "2020-04-10", "2020-04-11", "2020-04-11", 
"2020-04-23", "2020-04-24", "2020-05-02", "2020-04-28", "2020-04-29", 
"2020-04-30", "2020-05-01", "2020-05-02", "2020-05-03", "2020-05-04", 
"2020-05-05", "2020-05-06", "2020-04-01", "2020-04-05", "2020-04-06"
), Species_name = c("Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Lutra lutra", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", 
"Lutra lutra", "Vulpes vulpes", "Vulpes vulpes", "Lutra lutra", 
"Vulpes vulpes", "Lutra lutra", "Vulpes vulpes", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Lutra lutra", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes", "Vulpes vulpes", "Lutra lutra", 
"Lutra lutra", "Lutra lutra", "Lutra lutra", "Lutra lutra", "Lutra lutra", 
"Lutra lutra", "Lutra lutra", "Lutra lutra", "Vulpes vulpes", 
"Vulpes vulpes", "Vulpes vulpes"), Detection = c(0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
), Elevation = c(207, 213, 213, 213, 213, 213, 213, 213, 189, 
189, 189, 189, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 
169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 186, 
186, 186, 186, 186, 186, 186, 186, 186, 222, 222, 222)), row.names = c(NA, 
-46L), class = "data.frame")

I would like to have something that looks like the following, if it was the new data frame for Vulpes vulpes:

Camera.Trap.Name Sampling.Event Photo.Date  Species_name Detection Elevation
CT-Tst-5-1        Olney 7       2020-05-02  Vulpes vulpes      1       169
CT-Tst-8-1        Olney 7       2020-04-28   Lutra lutra       0       186
CT-Tst-8-1        Olney 7       2020-04-29   Lutra lutra       0       186

I have attempted to create list of unique species names, and create a loop that goes through the data frame, that changes the detection value to 1 if the names match, and finally create a new, updated data frame for that species. These were very unsuccessful so all help would be appreciated. Thanks

The approach you described is correct. However, you need to copy the data first before you modify the Detection value, so that you do not change the original data and the subsequent copies of it.

s = unique(df$Species_name)   # list of unique species names

m = list()   # empty list (to fill with copies of the data)

for (i in s) {
  temp = df  # make a copy of the data frame

   # change Detection to 1 where species name match
  temp$Detection[temp$Species_name==i] = 1 

  m[[i]] = temp # place the new data in the array
}

(the temp variable is just to make the code more readable. You can copy directly to m[[i]] )

now you will have m as a list containing 2 dataframes:

> m[["Vulpes vulpes"]]
....
12       CT-Tst-3-1        Olney 3 2019-11-16 Vulpes vulpes         1       189
13       CT-Tst-5-1        Olney 5 2020-03-24 Vulpes vulpes         1       169
14       CT-Tst-5-1        Olney 5 2020-03-25   Lutra lutra         0       169
15       CT-Tst-5-1        Olney 5 2020-03-26 Vulpes vulpes         1       169

and

> m[['Lutra lutra']]
....
12       CT-Tst-3-1        Olney 3 2019-11-16 Vulpes vulpes         0       189
13       CT-Tst-5-1        Olney 5 2020-03-24 Vulpes vulpes         0       169
14       CT-Tst-5-1        Olney 5 2020-03-25   Lutra lutra         1       169
15       CT-Tst-5-1        Olney 5 2020-03-26 Vulpes vulpes         0       169

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM