7

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

icedwater
  • 4,701
  • 3
  • 35
  • 50
Akos
  • 840
  • 2
  • 12
  • 22
  • 3
    I think you get an error because Your data.frame contains a nested data.frame names Month... – agstudy Jun 25 '13 at 11:28
  • @agstudy the help file says `write.table` can handle nested dataframes. My guess is that something's fouled up and the `&& ncol(xj)` code given in the error message is trying to process a non-matrix, hence `ncolxj)` returns `NULL`, and `R` hates "NULL" in a logical operation. – Carl Witthoft Jun 25 '13 at 12:00
  • Anyway, the obvious plan of attack is to try `write.table` on a portion of `df` , after removing candidate "bad" elements, and see which element is the culprit. – Carl Witthoft Jun 25 '13 at 12:02
  • 1
    @CarlWitthoft You can see my example. – agstudy Jun 25 '13 at 12:06
  • 2
    Yup -- looks like the documentation for `write.table` is incomplete. It can handle columns which are lists, but not nested lists. – Carl Witthoft Jun 25 '13 at 14:20
  • Thank you.. Your nested data frame and error statement was helpful.. Thanks – Sree Aurovindh Jul 14 '14 at 08:24
  • I met this issue with `write.table` when I created a data frame from a matrix via `as.data.frame`. The columns are created as lists of one-item lists then. – Palec Mar 10 '15 at 22:29

3 Answers3

6

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)))
agstudy
  • 119,832
  • 17
  • 199
  • 261
5

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")
Community
  • 1
  • 1
Flo
  • 1,503
  • 1
  • 18
  • 35
2

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

user3055034
  • 593
  • 1
  • 5
  • 14
  • jsonlite::flatten works really well to flatten a nested data frame. But the link you provided is dead. – Renhuai Oct 24 '17 at 16:09