Корректное смещение строк после импорта данных в R - PullRequest
0 голосов
/ 01 ноября 2018

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

Пример данных:

bad <- data.frame(c("Block","NA","NA","Block","NA","NA"),
                  c("1:","image2","image3","2:","image5","image6"),
                  c("image1","NA","NA","image4","NA","NA"))

Токовый выход:

names(bad) <- NULL
print(bad)
1 Block     1: image1
2    NA image2     NA
3    NA image3     NA
4 Block     2: image4
5    NA image5     NA
6    NA image6     NA

Желаемый выход:

1 Block 1: image1
2       NA image2
3       NA image3
4 Block 2: image4
5       NA image5
6       NA image6
7 #From 3 to 2 columns

Вопрос: Какой самый эффективный способ сделать это?

Что я пробовал / думал о: 1) Функция cleanme из data science (но она просто сохраняет строки данных там, где есть строка "Block" и устранить другие строки); 2) Не уверен, как это сделать, но в основном использую функцию gsub, чтобы заменить каждое значение столбца 2, который содержит [1: 5], за которым следует «:» на «Блок [1: 5]:», а затем перемещение всей этой строки влево (но проблема в том, что у меня также есть строки с датами, которые я не хочу свернуть и которые могут начинаться точно так же); 3) Даже если я использую функцию gsub для замены одной строки на другую, мне все равно придется свернуть столбцы, что я мог бы сделать с помощью функции paste, но опять же, я хочу свернуть или заменить только первые два столбцы каждой строки, которые начинаются со строки «Блок» - и я не уверен в спецификациях синтаксиса, чтобы объединить все это, или действительно ли я просто усложняю свою жизнь даром.

Примечание: Я делал уроки и т. Д., Но не могу найти способ сделать это специально. Пожалуйста, направьте меня к нужному посту / дубликату и удалите этот, если он уже существует. Спасибо!

Обновление

Слегка адаптируя приведенный ниже ответ earch к моей фактической структуре данных, я смог найти рабочее решение (мой набор данных сложнее, чем мой пример). Для справки:

# Continuing from example above
bad <- as.matrix(bad) # Note that I didn't need this step for my actual data but needed here

good <- lapply(1:nrow(bad), function(i) bad[i, !is.na(bad[i, ])]) # Transforms rows into lists

good <- lapply(good, function(x) {
  if (x[1] == "Block") { # If the row starts with the word "Block", then do the following:
    c(paste(x[1:2], collapse = " "), x[3:length(x)]) # Paste the first two cells collapsed together (so Block + the block number belonging to the next cell) while adding the remaining row cells
  } else {
    c(x) # Just put the row in a list (didn't worked without this step)
  }
})

good <- do.call(rbind, good) # Binds elements from list together
good <- as.data.frame(good) # Puts everything nicely in a neat dataframe
good

        V1     V2       V3
1 Block 1: image1 Block 1:
2       NA image2       NA
3       NA image3       NA
4 Block 2: image4 Block 2:
5       NA image5       NA
6       NA image6       NA

Как вы можете видеть, с моей модификацией, использующей этот пример данных, все еще есть небольшая проблема, которая заключается в том, что «Блок 2:» повторяется далее, но это не слишком большая проблема, и, по крайней мере, фактические данные выровнены. В моих реальных данных было еще много столбцов, так что этого не произошло, и при использовании этого решения третий и следующий столбцы фактически содержали время реакции и другую информацию.

1 Ответ

0 голосов
/ 01 ноября 2018

Как насчет следующего? Я не был уверен, хотите ли вы, чтобы «NA» был фактическим NA или строкой, но вы можете изменить приведенный ниже код, чтобы он тоже был. Я также не был уверен, что желаемый эффект заключался в том, что новый data.frame имеет два столбца или в какой-то ситуации было больше (или меньше). Я предположил первое.

> bad <- data.frame(
+   c("Block","NA","NA","Block","NA","NA"),
+   c("1:","image2","image3","2:","image5","image6"),
+   c("image1","NA","NA","image4","NA","NA")
+ )
> names(bad) <- NULL
> bad

1 Block     1: image1
2    NA image2     NA
3    NA image3     NA
4 Block     2: image4
5    NA image5     NA
6    NA image6     NA
> 
> bad <- as.matrix(bad)
> bad[bad == "NA"] <- NA
> 
> good <- lapply(1:nrow(bad), function(i) bad[i, !is.na(bad[i, ])])
> good <- lapply(good, function(x) {
+   if(length(x) == 1) {
+     c(NA, x)
+   } else {
+     c(paste(x[1:(length(x) - 1)], collapse = " "), x[length(x)])
+   }
+ })
> good <- do.call(rbind, good)
> good <- as.data.frame(good)
> good
        V1     V2
1 Block 1: image1
2     <NA> image2
3     <NA> image3
4 Block 2: image4
5     <NA> image5
6     <NA> image6
...