Я хочу создать data.frame со значениями, которые я печатаю этого цикла в R - PullRequest
0 голосов
/ 24 сентября 2018

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

filenames <- list.files(path=getwd())  
numfiles <- length(filenames)  
for (i in 1:numfiles) {
  file <- read.table(filenames[i],header = TRUE)
  ts = subset(file, file$name == "plantNutrientUptake")
  tss = subset (ts, ts$path == "//plants/nitrate")
  tssc = tss[,2:3]    
  d40 = tssc[41,2]
  print(d40)
  print(filenames[i]) 
} 

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Есть много способов сделать то, что вы просите.Кроме того, без воспроизводимого примера сложно проверить, будет ли выполняться код.Я не мог сказать, какой тип данных был в каждой из ваших переменных, поэтому я только предположил, что это были в основном символы с одним числом.Вам придется изменить код, если это не так.

Следующий метод использует базу R (никаких других пакетов).Это основано на том, что вы сделали.Есть и другие способы сделать это, используя map, do.call или apply.Но важно иметь возможность пройти через цикл.

Как кто-то прокомментировал, ваш код просто переписывает себя каждый цикл.К счастью, у вас есть переменная i, которую вы можете использовать, чтобы указать, куда идти.

filenames <- list.files(path=getwd())  
numfiles <- length(filenames)  

# Declare an empty dataframe for efficiency purposes
df <- data.frame(
  ts = rep(NA_character_,numfiles),
  tss = rep(NA_character_,numfiles),
  tssc = rep(NA_character_,numfiles),
  d40 = rep(NA_real_,numfiles),
  stringsAsFactors = FALSE
)

# Loop through the files and fill in the data
for (i in 1:numfiles){
  file <- read.table(filenames[i],header = TRUE)
  df$ts[i] <- subset(file, file$name == "plantNutrientUptake")
  df$tss[i] <- subset (ts, ts$path == "//plants/nitrate")
  df$tssc[i] <- tss[,2:3]    
  df$d40[i] <- tssc[41,2]
  print(d40)
  print(filenames[i]) 
} 

Вы заметите несколько дополнительных особенностей этого кода.

Во-первых, я явно объявляю тип переменной для каждого столбца.Вы можете использовать rep(NA,numfiles), но это оставляет R, чтобы угадать, каким должен быть столбец.Это не может быть проблемой для вас, если все ваши переменные явно одного типа.Но представьте, что у вас есть переменная a = c("1","A","B") всех символов.R пройдет первую итерацию цикла и предположит, что столбец числовой.Затем при втором запуске цикла произойдет сбой, когда он встретится с символом.

Далее я объявляю весь фрейм данных перед входом в цикл.Когда люди говорят вам, что циклы в [modern] R медленные, это часто происходит потому, что вы перераспределяете память для каждого цикла.Объявляя весь кадр данных заранее, вы значительно ускоряете цикл.Это также позволяет вам ссылаться на любую ячейку в кадре данных ... это именно то, что вы хотите сделать в цикле.

Наконец, я использую синтаксис $, чтобы прояснить ситуацию.Запись df[i,"d40"] <- d40 - это то же самое, что запись df$d40[i] <- d40.Я просто думаю, что понятно использовать второй метод.Это вопрос личных предпочтений.

0 голосов
/ 24 сентября 2018

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

filenames <- list.files(path=getwd())  
numfiles <- length(filenames)

# Create an empty data.frame
df <- data.frame(filename = rep(NA, numfiles), d40 = rep(NA, numfiles))

  for (i in 1:numfiles){
    file <- read.table(filenames[i],header = TRUE)
    ts = subset(file, file$name == "plantNutrientUptake")
    tss = subset (ts, ts$path == "//plants/nitrate")
    tssc = tss[,2:3]    
    d40 = tssc[41,2]

    # Fill row i of the data frame
    df[i,"filename"] = filenames[i]
    df[i,"d40"] = d40

}

Надеюсь, что это так!Удачи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...