R: символы, превращенные в NA после повторного связывания с пустым символьным фреймом данных

#r #loops #dataframe #rbind #r-factor

#r #циклы #фрейм данных #повторный связывание #r-фактор

Вопрос:

итак, мой вопрос может быть очень простым. Я ценю любую помощь, хотя:

Я пытаюсь разобрать вложенный список во фрейм данных, используя циклы. Для этого я сначала создал пустой фрейм данных с именами столбцов и всеми столбцами в виде символов:

 dat<-data.frame(a=character(0), b=character(0), c=character(0), d=character(0), e=character(0), f=character(0),stringsAsFactors=FALSE)
  

Прямо сейчас str (dat) вернул бы что-то вроде этого:

 'data.frame':   0 obs. of  6 variables:

 $ a: chr 
 $ b : chr 
 $ c: chr 
 $ d: chr 
 $ e: chr 
 $ f: chr 
  

Затем, используя циклы for, я смог извлечь список переменных из вложенного списка. Существует несколько вложенных циклов, работающих с несколькими вложенными фреймами данных, поэтому вот упрощенная версия:

 for(i in 1:3){
  a<-"sdfsaf"
  b<-"dfadasfsd"
  c<-"fdsfsadf"
  d<-"dfads"
  e<-"sfdsfdsf"
  f<-"dfsfsdf"
  dat<-rbind(dat,setNames(as.list(c(a,b,c,d,e,f)),names(dat)))    
}
  

После первого цикла (i==1) возвращаемая дата будет выглядеть следующим образом:

      a            b            c            d          e            f
2  sdfsaf      dfadasfsd    fdsfsadf        dfads     sfdsfdsf      dfsfsdf
  

Все выглядит хорошо. Однако после завершения всех трех циклов я получил примерно следующее:

  a            b            c            d          e            f
2  sdfsaf      dfadasfsd    fdsfsadf        dfads     sfdsfdsf      dfsfsdf
3 <NA>        <NA>       <NA>             <NA>        <NA>          <NA>
4  <NA>        <NA>       <NA>              <NA>      <NA>           <NA>
  

Теперь я проверил str (dat). Столбцы во фрейме данных превратились в множители! Это показывает что-то вроде этого:
‘data.frame’: 3 объекта из 6 переменных:

  $ a: Factor w/ 1 level "sdfsaf": 1 NA NA 
 $ b : Factor w/ 1 level "dfadasfsd": 1 NA NA
 $ c: Factor w/ 1 level "fdsfsadf": 1 NA NA
 $ d: Factor w/ 1 level "dfads": 1 NA NA
 $ e: Factor w/ 1 level "sfdsfdsf": 1 NA NA
 $ f: Factor w/ 1 level "dfsfsdf": 1 NA NA
  

Я использовал исходный код для отладки и убедился, что каждая переменная в каждом цикле не была NA или NULL. Я также использовал class (), чтобы убедиться, что каждая переменная имеет символьный тип — как вектор символов в сочетании с фреймом данных символьного типа может превратить все в факторы?

Пожалуйста, помогите. Спасибо.

Комментарии:

1. data.frame преобразует символы в множители, если у вас их нет stringsAsFactors = FALSE ; Я предполагаю, что это вызывается, когда вы rbind отправляете список в data.frame. Однако построение data.frame с for циклом действительно нецелесообразно; чего вы на самом деле пытаетесь достичь?

2. Спасибо! Я знаю, что мне, вероятно, следовало использовать tapply или lapply или apply, но for цикл просто проще обернуть вокруг этого вложенного списка / файла json. В основном данные, которые я хочу, взяты из фрейма данных с 16 столбцами, причем один из столбцов представляет собой вложенный список с тремя уровнями. Кроме того, количество элементов этого списка варьируется для каждой строки данных. Но теперь, используя метод @Arun kumar mahesh, я решил эту проблему. Мне нужно вернуться позже, чтобы найти более эффективный способ сделать это. Но сейчас у меня заканчивается время. Спасибо.

3. На самом деле, оказалось, что ваш совет был правильным: «Однако построение data.frame с циклом for действительно нецелесообразно». dat[,1:6] <-apply(dat[,1:6],2, as.character) Подход сначала, казалось, сработал. Затем я получил это сообщение об ошибке: Error in if (d2 == 0L) { : missing value where TRUE/FALSE needed после нескольких циклов. Я предполагаю, что apply вызовы функций if ? Иначе почему эта ошибка появилась бы сразу после dat[,1:6] <-apply(dat[,1:6],2, as.character) ? Пожалуйста, помогите.

Ответ №1:

 for(i in 1:3){
  dat<-rbind(dat,setNames(as.list(c(a,b,c,d,e,f)),names(dat)))

}

dat[,1:6] <-apply(dat[,1:6],2, as.character)

str(dat)
'data.frame':   3 obs. of  6 variables:
  $ a: chr  "sdfsaf" "sdfsaf" "sdfsaf"
$ b: chr  "dfadasfsd" "dfadasfsd" "dfadasfsd"
$ c: chr  "fdsfsadf" "fdsfsadf" "fdsfsadf"
$ d: chr  "dfads" "dfads" "dfads"
$ e: chr  "sfdsfdsf" "sfdsfdsf" "sfdsfdsf"
$ f: chr  "dfsfsdf" "dfsfsdf" "dfsfsdf"
  

Комментарии:

1. Большое спасибо. Я попробовал этот метод и сработал как чудо! Теперь у меня есть все мои символьные векторы, добавленные в пустой фрейм данных!

Ответ №2:

Замените rbind строку на:

 dat <- rbind(dat, setNames(as.list(c(a,b,c,d,e,f)), names(dat)), stringsAsFactors = FALSE)
  

Вот полный скрипт без выходных данных:

 > dat<-data.frame(a=character(0), b=character(0), c=character(0), d=character(0), e=character(0), f=character(0),stringsAsFactors=FALSE)
> for(i in 1:3){
    a<-"sdfsaf"
    b<-"dfadasfsd"
    c<-"fdsfsadf"
    d<-"dfads"
    e<-"sfdsfdsf"
    f<-"dfsfsdf"
    dat<-rbind(dat,setNames(as.list(c(a,b,c,d,e,f)),names(dat)),stringsAsFactors = FALSE)    
  }
> dat
       a         b        c     d        e       f
1 sdfsaf dfadasfsd fdsfsadf dfads sfdsfdsf dfsfsdf
2 sdfsaf dfadasfsd fdsfsadf dfads sfdsfdsf dfsfsdf
3 sdfsaf dfadasfsd fdsfsadf dfads sfdsfdsf dfsfsdf
  

Я получил этот ответ как в R 3.3.1, так и в версии для разработки R.

Комментарии:

1. Спасибо. Я только что попробовал это, но получил что-то вроде этого:

2. post_id автор тема типа контента, когда 2 post_id автор тема типа контента, когда stringsAsFactors ложное ложное ложное ложное ложное ложное 3 <NA> <NA> <NA> <NA> <NA> <NA> stringsAsFactors1 ложное ложное ложное ложное ложное ложное 5 <NA> <NA> <NA> <NA> <NA> <NA>

3. Я показал полный скрипт с выводом, и, как вы можете видеть, он дает ожидаемый ответ.

4. Я скопировал и запустил ваш полный скрипт в моем Rconsole, и вот что я получил:

5. для (i в 1: 3){ a<-«sdfsaf» b<-«dfadasfsd» c<-«fdsfsadf» d<-«dfads» e<-«sfdsfdsf» f<-«dfsfsdf» dat<-rbind(dat,setNames (as.list(c(a, b, c, d, e, f)), имена (dat)),stringsAsFactors = FALSE) } отладка в #2: a <просмотр «sdfsaf»[4]> dat [1] a b c d e f <0 строк> (или строки длиной 0.имена)