1

I have 7 of two different asc files loaded into R, asc[i] and wasc[i], [i] denotes that there are 1:7 ascs and wascs loaded into R. I need to combine the wasc[i] with the asc[i][[1]] (Just the first column in asc[i] with the whole wasc[i] file).

This should be repeated for every pair of asc and wasc files.

The code keeps giving me blank data frames, so I don't know why this doesn't work. The naming is correct, yet the code is not recognizing that the asc[i] and wasc[i] correlate with previously loaded files.

Any help will be greatly appreciated.

# These data frames will reproduce my issue 

asc1 <- data.frame(x= c(rep("A.tif", 20)), y = 1:20)
wasc1 <- data.frame(x= c(rep("B.tif", 20)), y = c(rep("Imager",20)))

asc2 <- data.frame(x= c(rep("A.tif", 20)), y = 1:20)
wasc2 <- data.frame(x= c(rep("B.tif", 20)), y = c(rep("Imager",20)))

asc3 <- data.frame(x= c(rep("A.tif", 20)), y = 1:20)
wasc3 <- data.frame(x= c(rep("B.tif", 20)), y = c(rep("Imager",20)))


for (i in 1:3) {
      d <- paste("asc", i, sep ="")
      f <- paste("wasc", i, sep ="")
      full_wing <- as.character(paste("full_wing", i, sep = ""))
      assign(full_wing,cbind(d[[1]], f))
    }

# Output of full_wing1 data frame

dput(full_wing1)

structure(c("asc1", "wasc1"), .Dim = 1:2, .Dimnames = list(NULL, 
c("", "f")))

Additional Information:

  1. asc files are 19 columns long
  2. wasc files are 13 columns long

I only want to combine column 1 from the asc file with the entire wasc file, thus cutting out the remaining 18 columns of the asc file.

Connor Murray
  • 313
  • 1
  • 8
  • 1
    Hi Connor, it would be great if you could prepare a reproducible example so we can cut and paste your code directly into our own R sessions, run it, and see what's going on. Sometimes this requires you preparing your data (or a representative subset of your data in the same format you are using) using `dput`. Thanks :) – mysteRious Oct 11 '18 at 03:49
  • @mysteRious I just added more background to my question. The code is producing an empty (2 column, 1 row) vector that is named properly but has NA's in place of actual data. – Connor Murray Oct 11 '18 at 04:08
  • Welcome to Stack Overflow! Could you make your problem reproducible by sharing a sample of your data so others can help (please do not use `str()`, `head()` or screenshot)? You can use the [`reprex`](https://reprex.tidyverse.org/articles/articles/magic-reprex.html) and [`datapasta`](https://cran.r-project.org/web/packages/datapasta/vignettes/how-to-datapasta.html) packages to assist you with that. See also [Help me Help you](https://speakerdeck.com/jennybc/reprex-help-me-help-you?slide=5) & [How to make a great R reproducible example?](https://stackoverflow.com/q/5963269) – Tung Oct 11 '18 at 04:30
  • I would love to attach two sample asc's, but I do not know how to include that into the question @Tung. Do you have a specific function I can use? – Connor Murray Oct 11 '18 at 04:49
  • @ConnorMurray: you can upload sample files to Google Drive, Dropbox or any other sites then add the links to your question – Tung Oct 11 '18 at 05:29
  • Using `cbind` in a `for` loop is indeed a problem, it's terribly inefficient. And working with sequentially named variables and `assign` is a real pain and potentially buggy, but putting them in a `list` works very well. See [How to make a list of data frames](https://stackoverflow.com/questions/17499013/how-do-i-make-a-list-of-data-frames) for a much much better way to do this, especially my answer. – Gregor Thomas Oct 11 '18 at 05:34
  • Regarding the reproducible example, *we do not want files in Dropbox*, we want *small*, illustrative examples in the question itself. Tung gave you several links, the `reprex` and `datapasta` packages have their own functions, and in base R you can use `dput`. Or just share code to create a little data frame, like `wasc = data.frame(x = 1, y = 2)`. – Gregor Thomas Oct 11 '18 at 05:36
  • 1
    Okay, I am sorry for the confusion everyone. I added some data frames that will reproduce the issues I am having. @Gregor – Connor Murray Oct 11 '18 at 17:10

1 Answers1

1
# put data in a list
asc = mget(ls(pattern = "^asc"))
wasc = mget(ls(pattern = "^wasc"))

full_wing = Map(f = function(w, a) cbind(w, a[[1]]), w = wasc, a = asc)

Map is a nice shortcut for iterating in parallel over multiple arguments. It returns a nice list. You can access the individual elements with, e.g., full_wing[[1]], full_wing[[3]], etc. Map is just a shortcut, the above code is basically equivalent to the for loop below:

results = list()
for (i in seq_along(asc)) {
    results[[i]] = cbind(wasc[[i]], asc[[i]][[1]])
}

I use mget to put the data in a list because in your example you already have objects like asc1, asc2, etc. A much better way to go is to never create those variables in the first place, instead read the files directly into a list, something like this:

asc_paths = list.files(pattern = "^asc")
asc = lapply(asc_paths, read.table)

You can see a lot more explanation of this at How to make a list of data frames?

If you only ever need one column of the asc files, another way to simplify this would be to only read in the needed column, see Only read limited number of columns for some recommendations there.

Gregor Thomas
  • 104,719
  • 16
  • 140
  • 257