StevenL
StevenL

Reputation: 99

extracting variable from file names in R

I have files that contain multiple rows, I want to add two new rows that I create by extracting varibles from the filename and multipling them by current rows. For example I have a bunch of file that are named something like this

file1[1000,1001].txt

file1[2000,1001].txt

between the [] there are always 2 numbers spearated by a comma

the file itself has multiple columns, for example column1 & column2

I want for each file to extract the 2 values in the name of the file and then use them as variables to make 2 new columns that used the variable to modify the values.

for example

file1[1000,2000]

the file contains two columns

column1    column2
1             2
2             4

I want at the end to add the first file name value to column 1 to create column3 and add the second file name value to column 2 to create column 4, ending up with something like this

column1  column2 column3 column4
1            2     1001     2002
2            4     1002     2004

thanks for the help. I am almost there just a few more issues original files has 2 columns "X_Parameter" "Y_Parameter", the file name is "test(64084,4224).txt your code works great at extracting the two values V1 "64084" and V2 "4224" from the file name. I then add these values to the original data set. this yields 4 columns. "X_Parameter" "Y_Parameter" "V1" "V2".

setwd("~/Desktop/txt/")
txt_names = list.files(pattern = ".txt")
for (i in 1:length(txt_names)){assign(txt_names[i], read.delim(txt_names[i]))
DS1 <- read.delim(file = txt_names[i], header = TRUE, stringsAsFactors = TRUE)
require(stringr)
remove_text <- str_extract(txt_names, pattern = "\\[[0-9,0-9]+\\]")
step1 <- gsub("(\\[)", "", remove_text)
step2 <- gsub("(\\])", "", step1)
DS2<-as.data.frame(do.call("rbind", (str_split(step2, ","))))
DS1$V1<-DS2$V1
DS1$V2<-DS2$V2

My issue arises when tying to sum "X_Parameter" and "V1" to make "absoluteX" and sum "Y_Parameter"with "V2" to make "absoluteY" for each row.

below are the two ways I have tried with the errors

DS1$absoluteX<-DS1$X_Parameter+DS1$V1

error In Ops.factor(DS1$X_Parameter, DS1$V1) : ‘+’ not meaningful for factors

other try was

DS1$absoluteX<-rowSums(DS1[,c(“X_Parameter”,”V1”)])

error Error in rowSums(DS1[, c("X_Parameter", "V1")]) : 'x' must be numeric

I have tried using

as.numeric(DS1$V1) 

that causes all values to become 1

Any thoughts?Thanks

Upvotes: 1

Views: 1709

Answers (2)

vagabond
vagabond

Reputation: 3594

## set path to wherever your files are
setwd("path")

## make a vector with names of your files
txt_names <- list.files(pattern = ".txt") # use this to make a complete list of names



## read your files in
for (i in 1:length(txt_names)) assign(txt_names[i], read.csv(txt_names[i], sep = "whatever your separator is"))


## for now I'm making a dummy vector and data frame
txt_names <- c("[1000,2000]")
ds1 <- data.frame(column1 = c(1,2), column2 = c(2,4))


## grab the text you require from the file names
require(stringr)

remove_text <- str_extract(txt_names, pattern = "\\[[0-9,0-9]+\\]")
step1 <- gsub("(\\[)", "", remove_text)
step2 <- gsub("(\\])", "", step1)

## step2 should look like this
> step2

[1] "1000,1001"

## split each string and convert to data frame with two columns 
ds2 <- as.data.frame(do.call("rbind", (str_split(step2, ","))))

## cbind with the file
df <- cbind(ds1, ds2)

## coerce factor columns to numeric
df$V1 <- as.numeric(as.character(df$V1))
df$V2 <- as.numeric(as.character(df$V2))

## perform the operation to change the columns

df$V1 <- df$column1 + df$V1
df$V2 <- df$column2 + df$V2

NOw you have a data.frame with two columns , each containing the file name parts you need. Just rep them times length of each of your data.frames and cbind.

Upvotes: 0

Peter Herman
Peter Herman

Reputation: 162

You can extract the numbers from a vector of file names as follows (not sure it is the shortest possible code, but it seems to work)

fnams<-c("file1[1000,2000].txt","file1[1500,2500].txt")
opsqbr<-regexpr("\\[",fnams)
comm<-regexpr(",",fnams)
clsqbr<-regexpr("\\]",fnams)
reslt<-data.frame(col1=as.numeric(substring(fnams,opsqbr+1,comm-1)),
                  col2=as.numeric(substring(fnams,comm+1,clsqbr-1)))
reslt

Which yields

  col1 col2
1 1000 2000
2 1500 2500

Once you have this data frame,it is easy to sequentially read the files and do the addition

Upvotes: 2

Related Questions