Multiply each other value in row with first value in row - r

I have the following data frame:
Date <- c("04.06.2013","05.06.2013","06.06.2013","07.06.2013","08.06.2013","09.06.2013")
discharge <- c("1000","2000","1100","3000","1700","1600")
concentration_1 <- c("25","20","11","6.4","17","16")
concentration_2 <- c("1.4","1.7","2.7","3.2","4","4.7")
concentration_3 <- c("1.2","1.3","1.9","2.2","2.4","3")
concentration_4 <- c("1","0.92","2.5","3","3.4","4.8")
y <- data.frame(Date, discharge,concentration_1,concentration_2,concentration_3,concentration_4, stringsAsFactors=FALSE)
y$Date <- as.Date(y$Date, format ="%d.%m.%Y")
y[-1] <- sapply(y[-1], as.numeric)
In each row, I need to multiply each concentration with the discharge.
I was looking into the apply function but couldnĀ“t figure out how to solve it.

No apply needed, just multiply. But first let's get your data in decent shape.
They way you define your data, because you use quotes around the numbers, all the columns that should be numeric are factors. We use lapply to convert them safely to numeric:
y <- data.frame(Date, discharge,concentration_1,concentration_2,concentration_3,concentration_4)
y$Date <- as.Date(y$Date, format ="%d.%m.%Y")
str(y)
# 'data.frame': 6 obs. of 6 variables:
# $ Date : Date, format: "2013-06-04" "2013-06-05" "2013-06-06" "2013-06-07" ...
# $ discharge : Factor w/ 6 levels "1000","1100",..: 1 5 2 6 4 3
# $ concentration_1: Factor w/ 6 levels "11","16","17",..: 5 4 1 6 3 2
# $ concentration_2: Factor w/ 6 levels "1.4","1.7","2.7",..: 1 2 3 4 5 6
# $ concentration_3: Factor w/ 6 levels "1.2","1.3","1.9",..: 1 2 3 4 5 6
# $ concentration_4: Factor w/ 6 levels "0.92","1","2.5",..: 2 1 3 4 5 6
# convert all columns but the first safely to numeric
y[, -1] = lapply(y[, -1], function(x) as.numeric(as.character(x)))
str(y)
# 'data.frame': 6 obs. of 6 variables:
# $ Date : Date, format: "2013-06-04" "2013-06-05" "2013-06-06" "2013-06-07" ...
# $ discharge : num 1000 2000 1100 3000 1700 1600
# $ concentration_1: num 25 20 11 6.4 17 16
# $ concentration_2: num 1.4 1.7 2.7 3.2 4 4.7
# $ concentration_3: num 1.2 1.3 1.9 2.2 2.4 3
# $ concentration_4: num 1 0.92 2.5 3 3.4 4.8
With that done, we can just multiply the concentration columns by the discharge column. R will "recycle" the discharge column to multiply each of the concentration columns appropriately.
concentration_columns = paste0("concentration_", 1:4)
y[, concentration_columns] = y[, concentration_columns] * y[, "discharge"]
y
# Date discharge concentration_1 concentration_2 concentration_3 concentration_4
# 1 2013-06-04 1000 25000 1400 1200 1000
# 2 2013-06-05 2000 40000 3400 2600 1840
# 3 2013-06-06 1100 12100 2970 2090 2750
# 4 2013-06-07 3000 19200 9600 6600 9000
# 5 2013-06-08 1700 28900 6800 4080 5780
# 6 2013-06-09 1600 25600 7520 4800 7680

The multiplication is vectorized, just use the columns you want to multiply as operands.
y[, 2] * y[, -(1:2)]

Once your values as not character (not in ""), you can use apply like this:
new <- data.frame(y[,1:2],apply(y[,3:6],2,function(x) x*y$discharge))

Related

unable to write to the csv file [duplicate]

I am trying to write a dataframe in R to a text file, however it is returning to following error:
Error in if (inherits(X[[j]], "data.frame") && ncol(xj) > 1L)
X[[j]] <- as.matrix(X[[j]]) :
missing value where TRUE/FALSE needed
I used the following command for the export:
write.table(df, file ='dfname.txt', sep='\t' )
I have no idea what the problem could stem from. As far as "missing data where TRUE/FALSE is needed", I have only one column which contains TRUE/FALSE values, and none of these values are missing.
Contents of the dataframe:
> str(df)
'data.frame': 776 obs. of 15 variables:
$ Age : Factor w/ 4 levels "","A","J","SA": 2 2 2 2 2 2 2 2 2 2 ...
$ Sex : Factor w/ 2 levels "F","M": 1 1 1 1 2 2 2 2 2 2 ...
$ Rep : Factor w/ 11 levels "L","NR","NRF",..: 1 1 4 4 2 2 2 2 2 2 ...
$ FA : num 61.5 62.5 60.5 61 59.5 59.5 59.1 59.2 59.8 59.9 ...
$ Mass : num 20 19 16.5 17.5 NA 14 NA 23 19 18.5 ...
$ Vir1 : num 999 999 999 999 999 999 999 999 999 999 ...
$ Vir2 : num 999 999 999 999 999 999 999 999 999 999 ...
$ Vir3 : num 40 999 999 999 999 999 999 999 999 999 ...
$ Location : Factor w/ 4 levels "Loc1",..: 4 4 4 4 4 4 2 2 2 2 ...
$ Site : Factor w/ 6 levels "A","B","C",..: 5 5 5 5 5 5 3 3 3 3 ...
$ Date : Date, format: "2010-08-30" "2010-08-30" ...
$ Record : int 35 34 39 49 69 38 145 112 125 140 ...
$ SampleID : Factor w/ 776 levels "AT1-A-F1","AT1-A-F10",..: 525 524 527 528
529 526 111 78
88 110 ...
$ Vir1Inc : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
$ Month :'data.frame': 776 obs. of 2 variables:
..$ Dates: Date, format: "2010-08-30" "2010-08-30" ...
..$ Month: Factor w/ 19 levels "Apr-2011","Aug-2010",..: 2 2 2 2
2 2 18 18 18 18 ...
I hope I've given enough/the right information ...
Many thanks,
Heather
An example to reproduce the error. I create a nested data.frame:
Month=data.frame(Dates= as.Date("2003-02-01") + 1:15,
Month=gl(12,2,15))
dd <- data.frame(Age=1:15)
dd$Month <- Month
str(dd)
'data.frame': 15 obs. of 2 variables:
$ Age : int 1 2 3 4 5 6 7 8 9 10 ...
$ Month:'data.frame': 15 obs. of 2 variables:
..$ Dates: Date, format: "2003-02-02" "2003-02-03" "2003-02-04" ...
..$ Month: Factor w/ 12 levels "1","2","3","4",..: 1 1 2 2 3 3 4 4 5 5 ...
No I try to save it , I reproduce the error :
write.table(dd)
Error in if (inherits(X[[j]], "data.frame") && ncol(xj) > 1L)
X[[j]] <- as.matrix(X[[j]]) : missing value where TRUE/FALSE needed
Without inverstigating, one option to remove the nested data.frame:
write.table(data.frame(subset(dd,select=-c(Month)),unclass(dd$Month)))
The solution by agstudy provides a great quick fix, but there is a simple alternative/general solution for which you do not have to specify the element(s) in your data.frame that was(were) nested:
The following bit is just copied from agstudy's solution to obtain the nested data.frame dd:
Month=data.frame(Dates= as.Date("2003-02-01") + 1:15,
Month=gl(12,2,15))
dd <- data.frame(Age=1:15)
dd$Month <- Month
You can use akhilsbehl's LinearizeNestedList() function (which mrdwab made available here) to flatten (or linearize) the nested levels:
library(devtools)
source_gist(4205477) #loads the function
ddf <- LinearizeNestedList(dd, LinearizeDataFrames = TRUE)
# ddf is now a list with two elements (Age and Month)
ddf <- LinearizeNestedList(ddf, LinearizeDataFrames = TRUE)
# ddf is now a list with 3 elements (Age, `Month/Dates` and `Month/Month`)
ddf <- as.data.frame.list(ddf)
# transforms the flattened/linearized list into a data.frame
ddf is now a data.frame without nesting. However, it's column names still reflect the nested structure:
names(ddf)
[1] "Age" "Month.Dates" "Month.Month"
If you want to change this (in this case it seems redundant to have Month. written before Dates, for example) you can use gsub and some regular expression that I copied from Sacha Epskamp to remove all text in the column names before the ..
names(ddf) <- gsub(".*\\.","",names(ddf))
names(ddf)
[1] "Age" "Dates" "Month"
The only thing left now is exporting the data.frame as usual:
write.table(ddf, file="test.txt")
Alternatively, you could use the "flatten" function from the jsonlite package to flatten the dataframe before export. It achieves the same result of the other functions mentioned and is much easier to implement.
jsonlite::flatten
https://rdrr.io/cran/jsonlite/man/flatten.html

How can I replace hyphen "cells" in R data frames with zeros?

I have a data frame with some positive numbers, some negative numbers, some words, and some hyphen "cells" in it, as such:
Revenue 73.88 74.76 78.02 78.19 68.74
Other Revenue - Total - - - - -
Total Revenue 73.88 74.76 78.02 78.19 68.74
Cost of Revenue - Total 21.09 21.61 23.01 22.76 19.99
Gross Profit 52.80 -53.15 -55.01 55.43 48.75
I want to replace the hyphens that are only found in the second to last columns with 0s, but only if the hyphens are not at the beginning of numbers. For example, I don't want to turn a negative number positive.
I've tried:
df[-1] <- lapply(df[-1], function(x) as.numeric(gsub("-", 0, x)))
but that returns the previous data frame as:
Revenue NA NA NA NA NA
Other Revenue - Total 0 0 0 0 0
Total Revenue NA NA NA NA NA
Cost of Revenue - Total NA NA NA NA NA
Gross Profit NA NA NA NA NA
which is something I definitely don't want. How can I fix this?
Thanks.
This is the output when I call str():
str(income)
'data.frame': 49 obs. of 6 variables:
$ Items : Factor w/ 49 levels "Accounting Change",..: 44 40 47 7 23 45 43 9 29 49 ...
$ Recent1: Factor w/ 14 levels "-","0.00","11,305.00",..: 4 1 4 11 14 6 5 1 1 1 ...
$ Recent2: Factor w/ 16 levels "-","-29.00","0.00",..: 5 1 5 15 16 9 6 1 1 2 ...
$ Recent3: Factor w/ 17 levels "-","0.00","11,449.00",..: 5 1 5 15 17 10 6 1 1 4 ...
$ Recent4: Factor w/ 18 levels "-","-31.00","0.00",..: 6 1 6 15 17 9 4 1 1 18 ...
$ Recent5: Factor w/ 14 levels "-","0.00","1,617.00",..: 4 1 4 10 13 5 3 1 1 1 ...
As #Joe hinted at, the values in a column of a data.frame have to be of the same type, so given that you have -s in the same vectors as what appear to be numerics (52.80, 21.09, etc...), each column is being forced to type character (presumably). Try gsubbing with "0" instead of 0 and then converting the columns to numeric. Since you are forcing a 0 into a character column vector, it is coercing the rest of the vector elements to NA.
DF <- data.frame(
X1=c(12,45,67,"-",9),
X2=c(34,45,56,"-",12))
str(DF)
'data.frame': 5 obs. of 2 variables:
$ X1: chr "12" "45" "67" "-" ...
$ X2: chr "34" "45" "56" "-" ...
##
DF2 <- DF
DF2$X1 <- gsub("-","0",DF2$X1)
DF2$X1 <- as.numeric(DF2$X1)
str(DF2)
'data.frame': 5 obs. of 2 variables:
$ X1: num 12 45 67 0 9
$ X2: chr "34" "45" "56" "-" ...
EDIT: To remove the commas in your values,
DF <- data.frame(
X0=c("A","B","C","D"),
X1=c("12,300.04","45.5","-","9,046.78"),
X2=c("1,0001.12","33","-","12.6"))
for(j in 2:ncol(DF)){
DF[,j] <- gsub(",","",as.character(DF[,j]))
for(i in 1:nrow(DF)){
if(nchar(DF[i,j])==1){
DF[i,j] <- gsub("-","0",DF[i,j])
} else {
next
}
}
DF[,j] <- as.numeric(DF[,j])
DF[,j]
}
There are more efficient ways of doing this with *apply functions and regular expressions but this should work. I had to account for the fact that some of your values are negative so assuming the cells with only a - in them are only one character long, this should fix them without affecting the negative values in other cells.
Assume it is named dat:
dat[2:6] <- lapply( dat[2:6], function(col) as.numeric( gsub("-$|\\,", "", col) ) )
dat[is.na(dat)] <- 0
Only replaces minus-signs at the end of a string, removes commas and the gsub coerces factors to character so you don't need to add as.character. When I imported your data using read.fwf and textConnection I got trailing spaces. You can either use gdata::trim to remove those first but this worked:
lapply(dat[2:6], function(col) as.numeric( gsub("-[ ]*$|\\,", "", col ) ) ) # on RHS
dat<-read.fwf(textConnection("Revenue 73.88 74.76 78.02 78.19 68.74
Other Revenue - Total - - - - -
Total Revenue 73.88 74.76 78.02 78.19 68.74
Cost of Revenue - Total 21.09 21.61 23.01 22.76 19.99
Gross Profit 52.80 -53.15 -55.01 55.43 48.75"), widths=c(24, rep(8,5)))
dat[2:6] <- lapply( dat[2:6], function(col) as.numeric( gsub("-$|\\,", "", col) ) )
dat[is.na(dat)] <- 0
dat
#----------
V1 V2 V3 V4 V5 V6
1 Revenue 73.88 74.76 78.02 78.19 68.74
2 Other Revenue - Total 0.00 0.00 0.00 0.00 0.00
3 Total Revenue 73.88 74.76 78.02 78.19 68.74
4 Cost of Revenue - Total 21.09 21.61 23.01 22.76 19.99
5 Gross Profit 52.80 -53.15 -55.01 55.43 48.75

How to approach loop with increasing variable name in R

My dataset is currently a set of answers to twenty questions with 300 observations.
Each of the questions are labled q1, q2, q3, etc.
Each observation gives a 1 to 10 response.
The code below is what I have. What I want is for the q1 to change when the counter changes in R.
totaltenq1 <- sum(UpdatedQualtrix$tenq1)
totalnineq1 <- sum(UpdatedQualtrix$nineq1)
totaleightq1 <- sum(UpdatedQualtrix$eightq1)
totalsevenq1 <- sum(UpdatedQualtrix$sevenq1)
totalsixq1 <- sum(UpdatedQualtrix$sixq1)
totalfiveq1 <- sum(UpdatedQualtrix$fiveq1)
totalfourq1 <- sum(UpdatedQualtrix$fourq1)
totalthreeq1 <- sum(UpdatedQualtrix$threeq1)
totaltwoq1 <- sum(UpdatedQualtrix$twoq1)
totaloneq1 <- sum(UpdatedQualtrix$oneq1)
totaltenq2 <- sum(UpdatedQualtrix$tenq2)
totalnineq2 <- sum(UpdatedQualtrix$nineq2)
totaleightq2 <- sum(UpdatedQualtrix$eightq2)
totalsevenq2 <- sum(UpdatedQualtrix$sevenq2)
totalsixq2 <- sum(UpdatedQualtrix$sixq2)
totalfiveq2 <- sum(UpdatedQualtrix$fiveq2)
totalfourq2 <- sum(UpdatedQualtrix$fourq2)
totalthreeq2 <- sum(UpdatedQualtrix$threeq2)
totaltwoq2 <- sum(UpdatedQualtrix$twoq2)
totaloneq2 <- sum(UpdatedQualtrix$oneq2)
I would like to have code that is
count = 20
for (i in 1:count){
totaltenq(i) <- sum(UpdatedQualtrix$tenq(i)
totalninq(I) <- sum(UpdatedQuatlrix$nineq(I)
etc
}
That way, when I do it again in the future, I can tell R how many questions it has the next time and it will change it. That way I don't have 10,000 lines of code from copying and pasting my code 20 times.
I don't think you need any loops at all. It just all depends on how you want to store those value. I'm a big fan of not having more variables than necessary.
Here's some sample data. I'll just make 10 rows (observations) with values 1-5.
set.seed(15)
Q<-3
numbs<-c("one","two","three","four","five","six","seven","eight","nine","ten")
qs<-paste0("q",1:Q)
qnumbs <- outer(numbs, qs, paste0)
UpdatedQualtrix <-data.frame(ID=1:10,
matrix(sample(1:5, 10*length(numbs)*Q, replace=T), nrow=10))
colnames(UpdatedQualtrix) <- c("ID",qnumbs)
Now I can sum up each of the columns with
( Qsums<-colSums(UpdatedQualtrix[, qnumbs]) )
# oneq1 twoq1 threeq1 fourq1 fiveq1 sixq1 sevenq1 eightq1 nineq1 tenq1
# 37 35 29 26 32 39 40 33 40 26
# oneq2 twoq2 threeq2 fourq2 fiveq2 sixq2 sevenq2 eightq2 nineq2 tenq2
# 37 31 19 29 25 38 36 35 28 27
# oneq3 twoq3 threeq3 fourq3 fiveq3 sixq3 sevenq3 eightq3 nineq3 tenq3
# 37 30 31 31 24 31 29 31 25 41
And if we want the totals per question we can do
sapply(qs, function(a, b) sum(Qsums[paste0(b,a)]), b=numbs)
# q1 q2 q3
# 337 305 310
Or if we want the counts per response we can do
sapply(numbs, function(a, b) sum(Qsums[paste0(a,b)]), b=qs)
# one two three four five six seven eight nine ten
# 111 96 79 86 81 108 105 99 93 94
You might want to also consider melting your data since it's so structured. You can use the reshape2 library to help. You can do
require(reshape2)
mm <- melt(UpdatedQualtrix, id.vars="ID")
mm <- cbind(mm[,-2], colsplit(mm$variable, "q", c("resp","q")))
mm$resp <- factor(mm$resp, levels=numbs)
to turn your data into a "tall" format so each value has it's own row with a column for ID, value, response and question.
str(mm)
# 'data.frame': 300 obs. of 4 variables:
# $ ID : int 1 2 3 4 5 6 7 8 9 10 ...
# $ value: int 4 1 5 4 2 5 5 2 4 5 ...
# $ resp : Factor w/ 10 levels "one","two","three",..: 1 1 1 1 1 1 1 1 1 1 ...
# $ q : int 1 1 1 1 1 1 1 1 1 1 ...
And then we can more easily do other calculations. Of you want the total scores by question, you could do
aggregate(value~q, mm, sum)
# q value
# 1 1 337
# 2 2 305
# 3 3 310
If you wanted the average value for each question/response you could do
with(mm, tapply(value, list(q,resp), mean))
# one two three four five six seven eight nine ten
# 1 3.7 3.5 2.9 2.6 3.2 3.9 4.0 3.3 4.0 2.6
# 2 3.7 3.1 1.9 2.9 2.5 3.8 3.6 3.5 2.8 2.7
# 3 3.7 3.0 3.1 3.1 2.4 3.1 2.9 3.1 2.5 4.1

Median plot per month with #obs. on second axis per month in r-studio

I have a data.frame consisting of 2 variables with each 2.5 million obs.
str(values)
data.frame': 2529905 obs. of 2 variables:
$ Date : Factor w/ 498 levels "1977-11","1978-06",..: 108 60 12 108 58 108 132 188 51 60 ...
$ Value: num 223000 171528 110269 426000 172436 ...
> head(values)
Date Value
1 2003-01 223000.0
2 1999-01 171528.0
3 1992-01 110268.6
4 2003-01 426000.0
5 1998-11 172436.5
6 2003-01 334000.0
I wanted to make a data.frame with the median per date:
library(plyr)
medianperdate = ddply(values, .(Date), summarize, median_value = median(Value))
> str(medianperdate)
'data.frame': 498 obs. of 2 variables:
$ Date : Factor w/ 498 levels "1977-11","1978-06",..: 1 2 3 4 5 6 7 8 9 10 ...
$ median_value: num 106638 84948 85084 75725 88487 ...
> head(medianperdate)
Date median_value
1 1977-11 106638.35
2 1978-06 84947.65
3 1985-07 85083.79
4 1986-05 75724.58
5 1986-11 88487.14
6 1986-12 98697.20
But what I want, is an extra column which counts the observations per month (eg. 2003-01, the data used would be object "values"
And another extra column where I define which class house it is:
a : < 200 000
b : < 300 000 & > 200 000
c : < 300 000 & > 2000000
I will continuetrying this but because I am already stuck for a couple of hours I will appreciate help very much!!
If it is not clear, what I can understand. The following testdataframe presents how I would like my dataframe to look like
> testdf
Year MedianValue HouseClass #Observations
1 1999-1 200000 B 501
2 1999-2 150000 A 664
3 1999-3 250000 C 555
Like my answer to your previous question 0
library(data.table)
dt <- data.table(df)
dt2 <- dt[,list(
medianvalue = median(value),
obs = .N
),
by = "Date"
]
dt2[,HouseClass := "c"]
dt2[obs < 300000,HouseClass := "b"]
dt2[obs < 200000,HouseClass := "a"]
You can write functions in the apply and apply like functions (which includes the plyr functions). It would look something like this:
ddply(values, .(Date), .fun = function(x) {
median <- median(x)
value <- ifelse(median < 200000, 'A', ifelse(median < 300000, 'B', 'C'))
n <- length(x)
return(c(median, value, n))
})

Error when exporting dataframe to text file in R

I am trying to write a dataframe in R to a text file, however it is returning to following error:
Error in if (inherits(X[[j]], "data.frame") && ncol(xj) > 1L)
X[[j]] <- as.matrix(X[[j]]) :
missing value where TRUE/FALSE needed
I used the following command for the export:
write.table(df, file ='dfname.txt', sep='\t' )
I have no idea what the problem could stem from. As far as "missing data where TRUE/FALSE is needed", I have only one column which contains TRUE/FALSE values, and none of these values are missing.
Contents of the dataframe:
> str(df)
'data.frame': 776 obs. of 15 variables:
$ Age : Factor w/ 4 levels "","A","J","SA": 2 2 2 2 2 2 2 2 2 2 ...
$ Sex : Factor w/ 2 levels "F","M": 1 1 1 1 2 2 2 2 2 2 ...
$ Rep : Factor w/ 11 levels "L","NR","NRF",..: 1 1 4 4 2 2 2 2 2 2 ...
$ FA : num 61.5 62.5 60.5 61 59.5 59.5 59.1 59.2 59.8 59.9 ...
$ Mass : num 20 19 16.5 17.5 NA 14 NA 23 19 18.5 ...
$ Vir1 : num 999 999 999 999 999 999 999 999 999 999 ...
$ Vir2 : num 999 999 999 999 999 999 999 999 999 999 ...
$ Vir3 : num 40 999 999 999 999 999 999 999 999 999 ...
$ Location : Factor w/ 4 levels "Loc1",..: 4 4 4 4 4 4 2 2 2 2 ...
$ Site : Factor w/ 6 levels "A","B","C",..: 5 5 5 5 5 5 3 3 3 3 ...
$ Date : Date, format: "2010-08-30" "2010-08-30" ...
$ Record : int 35 34 39 49 69 38 145 112 125 140 ...
$ SampleID : Factor w/ 776 levels "AT1-A-F1","AT1-A-F10",..: 525 524 527 528
529 526 111 78
88 110 ...
$ Vir1Inc : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
$ Month :'data.frame': 776 obs. of 2 variables:
..$ Dates: Date, format: "2010-08-30" "2010-08-30" ...
..$ Month: Factor w/ 19 levels "Apr-2011","Aug-2010",..: 2 2 2 2
2 2 18 18 18 18 ...
I hope I've given enough/the right information ...
Many thanks,
Heather
An example to reproduce the error. I create a nested data.frame:
Month=data.frame(Dates= as.Date("2003-02-01") + 1:15,
Month=gl(12,2,15))
dd <- data.frame(Age=1:15)
dd$Month <- Month
str(dd)
'data.frame': 15 obs. of 2 variables:
$ Age : int 1 2 3 4 5 6 7 8 9 10 ...
$ Month:'data.frame': 15 obs. of 2 variables:
..$ Dates: Date, format: "2003-02-02" "2003-02-03" "2003-02-04" ...
..$ Month: Factor w/ 12 levels "1","2","3","4",..: 1 1 2 2 3 3 4 4 5 5 ...
No I try to save it , I reproduce the error :
write.table(dd)
Error in if (inherits(X[[j]], "data.frame") && ncol(xj) > 1L)
X[[j]] <- as.matrix(X[[j]]) : missing value where TRUE/FALSE needed
Without inverstigating, one option to remove the nested data.frame:
write.table(data.frame(subset(dd,select=-c(Month)),unclass(dd$Month)))
The solution by agstudy provides a great quick fix, but there is a simple alternative/general solution for which you do not have to specify the element(s) in your data.frame that was(were) nested:
The following bit is just copied from agstudy's solution to obtain the nested data.frame dd:
Month=data.frame(Dates= as.Date("2003-02-01") + 1:15,
Month=gl(12,2,15))
dd <- data.frame(Age=1:15)
dd$Month <- Month
You can use akhilsbehl's LinearizeNestedList() function (which mrdwab made available here) to flatten (or linearize) the nested levels:
library(devtools)
source_gist(4205477) #loads the function
ddf <- LinearizeNestedList(dd, LinearizeDataFrames = TRUE)
# ddf is now a list with two elements (Age and Month)
ddf <- LinearizeNestedList(ddf, LinearizeDataFrames = TRUE)
# ddf is now a list with 3 elements (Age, `Month/Dates` and `Month/Month`)
ddf <- as.data.frame.list(ddf)
# transforms the flattened/linearized list into a data.frame
ddf is now a data.frame without nesting. However, it's column names still reflect the nested structure:
names(ddf)
[1] "Age" "Month.Dates" "Month.Month"
If you want to change this (in this case it seems redundant to have Month. written before Dates, for example) you can use gsub and some regular expression that I copied from Sacha Epskamp to remove all text in the column names before the ..
names(ddf) <- gsub(".*\\.","",names(ddf))
names(ddf)
[1] "Age" "Dates" "Month"
The only thing left now is exporting the data.frame as usual:
write.table(ddf, file="test.txt")
Alternatively, you could use the "flatten" function from the jsonlite package to flatten the dataframe before export. It achieves the same result of the other functions mentioned and is much easier to implement.
jsonlite::flatten
https://rdrr.io/cran/jsonlite/man/flatten.html

Resources