R:Format the Text File Output

Formatting into text file in R

Here's a way:

# create the string
text <- paste0(sapply(unique(dat$Animal), function(x) {
subdat <- dat[dat$Animal == x, -1]
subdat[[2]] <- sprintf("%03d", subdat[[2]])
paste0("<", x, ">\n",
paste(capture.output(write.table(subdat, sep = "\t",
quote = FALSE, row.names = FALSE,
col.names = FALSE)), collapse = "\n"),
"\n</", x, ">")
}), collapse = "\n\n")

# write it to a file
write(text, file = "filename.txt")

The resulting file:

<dog>
steak 100
beef 200
poo 001
</dog>

<cat>
milk 020
steak 100
beef 200
</cat>

The columns are tab-delimited.

R - Output a text file from a dataframe with a specific format

We can do a split in. base R into a list of vectors

df2 <- transform(df1, NameRemarks = paste(Name, Remarks,
sep=" - "))[, c("NameRemarks", "Occupation", "Countrycode")]
lst1 <- lapply(split(df2[-3], df2$Countrycode),
function(x) split(x['NameRemarks'], x$Occupation))
#$`1`
#$`1`$Engineer
# NameRemarks
#1 Mark - Ok
#2 Jerry - None

#$`2`
#$`2`$Shepherd
# NameRemarks
#5 Max - Ok

#$`2`$Veterinarian
# NameRemarks
#3 Marie - Ok
#4 Nolan - Ok

The format may not fit well in writing the file. One option is capture.output

Map(capture.output, lst1, file = paste0("output", seq_along(lst1), ".txt"))

-output

Sample Image

For storing purpose, it may be better to do a single split

lst1 <- split(df2[-3], df2$Countrycode)
lapply(names(lst1), function(x) write.csv(lst1[[x]],
file = paste0("output", x, ".csv"), row.names = FALSE, quote = FALSE))

Or another option is tidyverse

library(dplyr)
library(tidyr)
library(stringr)
df1 %>%
unite(NameRemarks, Name, Remarks, sep= " - ") %>%
group_by(Countrycode) %>%
mutate(rn = row_number()) %>%
ungroup %>%
pivot_wider(names_from = Occupation, values_from = NameRemarks)
# A tibble: 5 x 5
# Countrycode rn Engineer Veterinarian Shepherd
# <int> <int> <chr> <chr> <chr>
#1 1 1 Mark - Ok <NA> <NA>
#2 1 2 Jerry - None <NA> <NA>
#3 2 1 <NA> Marie - Ok <NA>
#4 2 2 <NA> Nolan - Ok <NA>
#5 2 3 <NA> <NA> Max - Ok

data

df1 <- structure(list(Name = c("Mark", "Jerry", "Marie", "Nolan", "Max"
), Occupation = c("Engineer", "Engineer", "Veterinarian", "Veterinarian",
"Shepherd"), Countrycode = c(1L, 1L, 2L, 2L, 2L), Remarks = c("Ok",
"None", "Ok", "Ok", "Ok")), class = "data.frame", row.names = c(NA,
-5L))

Write a data.frame to a text file with certain format in R

Just provide a sep= argument that suits. Here is an example for 6 spaces followed by a tab:

R> head(trees)
Girth Height Volume
1 8.3 70 10.3
2 8.6 65 10.3
3 8.8 63 10.2
4 10.5 72 16.4
5 10.7 81 18.8
6 10.8 83 19.7
R> write.table(trees, sep=" \t",
+ file="/tmp/trees6spaces.txt", row.names=FALSE, col.names=FALSE)
R> system("head /tmp/trees6spaces.txt")
8.3 70 10.3
8.6 65 10.3
8.8 63 10.2
10.5 72 16.4
10.7 81 18.8
10.8 83 19.7
11 66 15.6
11 75 18.2
11.1 80 22.6
11.2 75 19.9
R>

Write lines of text to a file in R

fileConn<-file("output.txt")
writeLines(c("Hello","World"), fileConn)
close(fileConn)

Writing data to text file using write() in R in specific layout

Assuming your data is in a vector, I'll use letters:

nth <- 3
write(
paste(
sapply(split(letters, cumsum(seq_along(letters) %% nth == 1)),
paste, collapse = "\n"),
collapse = "\n\n"
),
file = "quux.txt"
)

How to save R output data to a text file

As Stéphane Laurent noted, you can save the output with

cat(text, file = "myfile.txt")

If you want to create a dataframe, you could use the text object directly. For example:

df <- data.frame("text" = text)

Alternatively, if you want to save your file and then read it in, I would propose you choose a file format which is more suited for storing tables. I.e. csv.

write.csv(text, file = "text.csv", row.names = FALSE)

df <- read.csv("text.csv")

Import text file to R and change it's format

Solution 1

That looks a lot like javascript code. Execute the javascript (using a web browser) and save the result to JSON, then open the file with R with jsonlite.

With your example, create this file and save it as my_page.html:

<html>
<header>
<script>

// Initialize locations to be able to push more values in it
// probably not required with your full code
var locations = [];

vLatitude ='23.8145833';
vLongitude ='90.4043056';
vcontents ='LRP: LRPS</br>Start of Road From the End of Banani Rail Crossing Over Pass</br>Division:Gazipur</br>Sub-Division:Tongi';

vLocations = new Array(vcontents, vLatitude, vLongitude);
locations.push(vLocations);

// convert locations to json
var jsonData = JSON.stringify(locations);

// actually write the json to file
function download(content, fileName, contentType) {
var a = document.createElement("a");
var file = new Blob([content], {type: contentType});
a.href = URL.createObjectURL(file);
a.download = fileName;
a.click();
}
download(jsonData, 'export_json.txt', 'text/plain');

</script>
</header>
<body>
Download should start automatically. You can look at the web console for errors.
</body>
</html>

When you open it with your web browser it should "download" a file, that you can open with R:

jsonlite::read_json("export_json.txt",simplifyVector = TRUE)

One problem is that the javascript code is created an array without names. So the names are not exported. I don't see how you could make javascript export it.

Solution 2

Instead of relying on a browser to execute the javascript code, you could do it directly in R with a javascript engine. It should give you the same result, but makes communication between the two easier.

Solution 3

If the file really looks like that all along, you might be able to remove the javascript lines that organize the arrays, and only keep the lines that define variables. In R, the symbols = and ; are technically valid, it's not too hard to rewrite the javascript into R code. Note this solution could be very fragile depending on what else is in your javascript code!

js_script <- "var locations = [];

vLatitude ='23.8145833';
vLongitude ='90.4043056';
vcontents ='LRP: LRPS</br>Start of Road From the End of Banani Rail Crossing Over Pass</br>Division:Gazipur</br>Sub-Division:Tongi';

vLocations = new Array(vcontents, vLatitude, vLongitude);
locations.push(vLocations);

// convert locations to json
var jsonData = JSON.stringify(locations);" %>%
str_split(pattern = "\n", simplify=TRUE) %>%
as.character() %>%
str_trim()

# Find the lines that look like defining variables
js_script <- js_script[str_detect(js_script, pattern = "^\\w+ ?= ?'.*' ?;$")]

# make it into an R expression
r_code <- str_remove(js_script, ";$") %>%
paste(collapse = ",")

r_code <- paste0("c(", r_code, ")")

# Execute
eval(str2expression(r_code))

how to write into .txt file in R?

(edited for better consistency with the OP)

In base R you can do it in just one line using as.data.frame.table:

df <- data.frame(
V1 = c("A", "B", "C", "D", "A", "A", "C"),
V2 = c("a", "a", "b", "c", "b", "d", "c"))
tableForData <- with(df, table(V1,V2))
tableForData[tableForData > 1] <- 1
t3 <- as.data.frame(tableForData) #this is the working part :)

Then t3 is...

> head(t3)
V1 V2 Freq
1 A a 1
2 B a 1
3 C a 0
4 D a 0
5 A b 1
6 B b 0

You can sort it if the order of rows is important:

t3 <- t3[order(t3$V1),]

... and write into a file:

write.table(t3, "afilename.csv", sep=";", col.names=FALSE, quote=FALSE, row.names=FALSE)

Loading txt file into R and replace some value based on other data frame

EDIT - added id to lookup to distinguish between non-unique House_id.

Here's an approach where I read the data, join to the updated weights in df, and then create an updated value on the rows that start with "M" using that new weight.

library(tidyverse)
read_fwf("txt_sample.txt" , col_positions = fwf_empty("txt_sample.txt")) %>% # edit suggested by DanG

# if the row starts with H, extract 8 digit house number and
# use that to join to the table with new weights
mutate(House_id = if_else(str_starts(X1, "H"), as.numeric(str_sub(X1, 2,9)), NA_real_),
id = if_else(str_starts(X1, "M"), str_sub(X1, 1,3), NA_character_)) %>%
fill(House_id) %>%
left_join(df, by = c("House_id", "id")) %>%
fill(new_weight) %>%

# make new string using updated weight (or keep existing string)
mutate(X1_new = coalesce(
if_else(str_starts(X1, "M"),
paste0(word(X1, end = 2, sep = "_"), "_W", new_weight),
NA_character_),
X1)) %>%

pull(X1_new) %>%
writeLines()

Output

H18105265_0
R1_0
Mab_3416311514210525745_W4567
T1_0
T2_0
T3_0
V64_0_2_010_ab171900171959
H18117631_0
R1_0
Maa_1240111711220682016_W3367
T1_0
V74_0_1_010_aa081200081259_aa081600081859_aa082100095659_aa095700101159_aa101300105059
H18121405_0
R1_0
Mab_2467211713110643835_W4500
T1_0
T2_0
V62_0_1_010_090500092459_100500101059_101100101659_140700140859_141100141359
H71811763_0
R1_0
Maa_5325411210120486554_W2455
Mab_5325411210110485554_W2872
T1_0
T2_0
T3_0
T4_0


Related Topics



Leave a reply



Submit