Создайте столбец вектора символов предопределенного текста и привяжите его к существующему фрейму данных с помощью rbind или bind_rows.

Добрый день,

Я представлю две [вероятно] очень маленькие задачи для вашего превосходного обзора.

Проблема №1

У меня есть относительно аккуратный df (dat) с dim 10299 x 563. 563 переменные, общие для обоих наборов данных [которые создали] dat: 'subject' (числовой), 'label' (числовой), 3 : 563 (имена переменных из текстового файла). Наблюдения 1: 2947 взяты из «тестового» набора данных, тогда как наблюдения 2948: 10299 взяты из «обучающего» набора данных.

Я хотел бы вставить столбец (header = 'type') в dat, который в основном представляет собой строки 1: 2947, состоящие из строки test и строк 2948: 10299 строки train таким образом я могу позже сгруппировать набор данных или другие подобные агрегатные функции в dplyr / tidyr.

Я создал тестовый df (testdf = 1: 10299: dim (testdf) = 102499 x 1), а затем:

testdat[1:2947 , "type"] <- c("test")
testdat[2948:10299, "type"] <- c("train")
> head(ds, 2);tail(ds, 2)
  X1.10299 type
1        1 test
2        2 test
      X1.10299  type
10298    10298 train
10299    10299 train

Так что мне очень не нравится, что сейчас есть столбец X1.10299.

Вопросы:

  • Есть ли лучший и более целесообразный способ создать столбец, в котором будет то, что я ищу, на основе моего вышеупомянутого варианта использования?
  • Как лучше всего вставить этот столбец в dat, чтобы потом использовать его для группировки с помощью dplyr?

Проблема №2

Я пришел к моему [почти] аккуратному df (dat) сверху: два взять dfs (test и train) dim (2947 x 563 и 7352 x 563), соответственно, и rbinding их вместе.

Я подтверждаю, что все мои имена переменных присутствуют после попытки привязки, примерно так:

test.names <- names(test)
train.names <- names(train)
identical(test.names, train.names)
> TRUE

Что интересно и вызывает наибольшую озабоченность, так это то, что если я попытаюсь использовать функцию bind_rows из dplyr для выполнения того же упражнения по привязке:

dat <- bind_rows(test, train)

Он возвращает фрейм данных, который, по-видимому, сохраняет все мои наблюдения (x: 10299), но теперь количество моих переменных уменьшено с 563 до 470!

Вопрос:

  • Кто-нибудь знает, почему мои переменные рубятся?
  • Это лучший способ объединить два dfs одной и той же структуры для последующего нарезания / нарезки кубиками с помощью dplyr /

тидыр?

Спасибо за ваше время и внимание к этим вопросам.

Пример тестовых / обучающих файлов dfs для просмотра (крайние слева цифры - это индексы df):

test df test [1:10, 1: 5]

   subject labels tBodyAcc-mean()-X tBodyAcc-mean()-Y tBodyAcc-mean()-Z
1        2      5         0.2571778       -0.02328523       -0.01465376
2        2      5         0.2860267       -0.01316336       -0.11908252
3        2      5         0.2754848       -0.02605042       -0.11815167
4        2      5         0.2702982       -0.03261387       -0.11752018
5        2      5         0.2748330       -0.02784779       -0.12952716
6        2      5         0.2792199       -0.01862040       -0.11390197
7        2      5         0.2797459       -0.01827103       -0.10399988
8        2      5         0.2746005       -0.02503513       -0.11683085
9        2      5         0.2725287       -0.02095401       -0.11447249
10       2      5         0.2757457       -0.01037199       -0.09977589

поезд df поезд [1:10, 1: 5]

   subject label tBodyAcc-mean()-X tBodyAcc-mean()-Y tBodyAcc-mean()-Z
1        1     5         0.2885845      -0.020294171        -0.1329051
2        1     5         0.2784188      -0.016410568        -0.1235202
3        1     5         0.2796531      -0.019467156        -0.1134617
4        1     5         0.2791739      -0.026200646        -0.1232826
5        1     5         0.2766288      -0.016569655        -0.1153619
6        1     5         0.2771988      -0.010097850        -0.1051373
7        1     5         0.2794539      -0.019640776        -0.1100221
8        1     5         0.2774325      -0.030488303        -0.1253604
9        1     5         0.2772934      -0.021750698        -0.1207508
10       1     5         0.2805857      -0.009960298        -0.1060652

Фактический код (игнорируйте вызовы функций / большую часть тестирования я тестирую через консоль).

[http://archive.ics.uci.edu/ml/machine-learning-databases/00240/estiveThe, который я использую с этим кодом. 1

run_analysis <- function () {
    #Vars available for use throughout the function that should be preserved
    vars <- read.table("features.txt", header = FALSE, sep = "")
    lookup_table <- data.frame(activitynum = c(1,2,3,4,5,6), 
                               activity_label = c("walking", "walking_up", 
                                                  "walking_down", "sitting", 
                                                  "standing", "laying"))
    test <- test_read_process(vars, lookup_table)
    train <- train_read_process(vars, lookup_table)
}

test_read_process <- function(vars, lookup_table) {
    #read in the three documents for cbinding later
    test.sub <- read.table("test/subject_test.txt", header = FALSE)
    test.labels <- read.table("test/y_test.txt", header = FALSE)
    test.obs <- read.table("test/X_test.txt", header = FALSE, sep = "")

    #cbind the cols together and set remaining colNames to var names in vars
    test.dat <- cbind(test.sub, test.labels, test.obs)  
    colnames(test.dat) <- c("subject", "labels", as.character(vars[,2]))

    #Use lookup_table to set the "test_labels" string values that correspond
    #to their integer IDs
    #test.lookup <- merge(test, lookup_table, by.x = "labels", 
    #               by.y ="activitynum", all.x = T)

    #Remove temporary symbols from globalEnv/memory
    rm(test.sub, test.labels, test.obs)

    #return
    return(test.dat)
}

train_read_process <- function(vars, lookup_table) {
    #read in the three documents for cbinding
    train.sub <- read.table("train/subject_train.txt", header = FALSE)
    train.labels <- read.table("train/y_train.txt", header = FALSE)
    train.obs <- read.table("train/X_train.txt", header = FALSE, sep = "")

    #cbind the cols together and set remaining colNames to var names in vars
    train.dat <- cbind(train.sub, train.labels, train.obs)    
    colnames(train.dat) <- c("subject", "label", as.character(vars[,2]))

    #Clean up temporary symbols from globalEnv/memory
    rm(train.sub, train.labels, train.obs, vars)

    return(train.dat)
}

person Zach    schedule 11.05.2015    source источник
comment
Привет, Зак, это определенно любопытно, потому что ничто в том, что ты делаешь, не кажется мне чем-то, что могло бы произвести то, что ты видишь. Можете ли вы продублировать это поведение с помощью подмножества данных, которое вы могли бы воспроизвести здесь (меньшее количество строк / столбцов, которые могут быть dput() или прочитаны?   -  person Forrest R. Stevens    schedule 11.05.2015
comment
@ ForrestR.Stevens Обновил вопрос с помощью воспроизводимого [надеюсь] набора данных.   -  person Zach    schedule 11.05.2015


Ответы (1)


Проблема, с которой вы сталкиваетесь, проистекает из того факта, что у вас есть дублированные имена в списке переменных, который вы используете для создания своих объектов фрейма данных. Если вы убедитесь, что имена столбцов уникальны и являются общими для всех объектов, код будет запущен. Я включил полностью рабочий пример на основе кода, который вы использовали выше (с исправлениями и различными правками, отмеченными в комментариях):

vars <- read.table(file="features.txt", header=F, stringsAsFactors=F)

##  FRS: This is the source of original problem:
duplicated(vars[,2])
vars[317:340,2]
duplicated(vars[317:340,2])
vars[396:419,2]

##  FRS: I edited the following to both account for your data and variable
##    issues:
test_read_process <- function() {
  #read in the three documents for cbinding later
  test.sub <- read.table("test/subject_test.txt", header = FALSE)
  test.labels <- read.table("test/y_test.txt", header = FALSE)
  test.obs <- read.table("test/X_test.txt", header = FALSE, sep = "")

  #cbind the cols together and set remaining colNames to var names in vars
  test.dat <- cbind(test.sub, test.labels, test.obs)  
  #colnames(test.dat) <- c("subject", "labels", as.character(vars[,2]))
  colnames(test.dat) <- c("subject", "labels", paste0("V", 1:nrow(vars)))

  return(test.dat)
}

train_read_process <- function() {
  #read in the three documents for cbinding
  train.sub <- read.table("train/subject_train.txt", header = FALSE)
  train.labels <- read.table("train/y_train.txt", header = FALSE)
  train.obs <- read.table("train/X_train.txt", header = FALSE, sep = "")

  #cbind the cols together and set remaining colNames to var names in vars
  train.dat <- cbind(train.sub, train.labels, train.obs)    
  #colnames(train.dat) <- c("subject", "labels", as.character(vars[,2]))
  colnames(train.dat) <- c("subject", "labels", paste0("V", 1:nrow(vars)))

  return(train.dat)
}


test_df <- test_read_process()
train_df <- train_read_process()

identical(names(test_df), names(train_df))


library("dplyr")

## FRS: These could be piped together but I've kept them separate for clarity:
train_df %>%
  mutate(test="train") -> 
  train_df

test_df %>%
  mutate(test="test") -> 
  test_df

test_df %>% 
  bind_rows(train_df) -> 
  out_df

head(out_df)
out_df

##  FRS: You can set your column names to those of the original 
##    variable list but you still have duplicates to deal with:
names(out_df) <- c("subject", "labels", as.character(vars[,2]), "test")

duplicated(names(out_df))
person Forrest R. Stevens    schedule 11.05.2015
comment
очень интересно! Вы думаете, что причина, по которой у меня есть дельта столбцов между rbind и bind_rows, заключается в том, что bind_rows удаляет столбцы с не буквенно-цифровыми символами? - person Zach; 11.05.2015
comment
Я не знаю, не видя фактических отрывков из вашего кода и того, как считываются все ваши данные. Но из ваших проверок, приведенных выше с identical(), похоже, что это не так? Как я уже сказал, я был озадачен таким результатом и не мог видеть очевидной причины, по которой вы бы это испытали, особенно если бы все типы данных были одинаковыми и т. Д. (bind_rows() будет заблокирован, если типы данных столбца смешаны). - person Forrest R. Stevens; 11.05.2015
comment
Обновлен исходный пост, чтобы включить реальный код, который я написал до сих пор через консольное тестирование. - person Zach; 11.05.2015
comment
Что ж, я все еще не могу объяснить, что вы наблюдаете, без исходных файлов данных я могу застрять. Я отредактировал приведенный выше код, чтобы включить в него исходные имена столбцов, думая, что это может быть странность в проверке имени dplyr, но я все еще не понимаю, почему bind_rows() будет выполняться без ошибок, но в конечном итоге приведет к удалению столбцов. Как правило, если имена столбцов не совпадают, столбцы сохраняются, а НП заполняются. - person Forrest R. Stevens; 11.05.2015
comment
Привет, @Forrest, я добавил ссылку на набор данных, который я использую, прямо перед блоком кода. Это необычное поведение. - person Zach; 11.05.2015
comment
Я переработал свой код, чтобы отразить происходящее, а именно то, что список переменных, который вы использовали для переименования данных при чтении (файл features.txt), содержит повторяющиеся имена столбцов. - person Forrest R. Stevens; 12.05.2015
comment
Спасибо, что заглянули в это. Я бы никогда не ожидал, что имена переменных будут дублироваться в исходном файле. Какая сбивающая с толку переменная (полностью задуманный каламбур), которая показала довольно простое упражнение по наведению порядка на пути к приключениям. Я изучу ваши решения и посмотрю, что я могу использовать в своих целях для очистки переменных. - person Zach; 12.05.2015
comment
Меня просто поразило, что dplyr, возможно, распознал повторяющиеся столбцы и удалил их по умолчанию. Вы думаете, что это так? - person Zach; 12.05.2015
comment
Я тестировал это на dplyr 0.4.1, и он выдает Error: duplicated column name, когда я пытаюсь выполнить вызов bind_rows(). Честно говоря, я понятия не имею, почему вы увидели упавшие столбцы. Может, у других есть? - person Forrest R. Stevens; 12.05.2015
comment
Ух ты. Я пробовал это в двух разных средах с RStudio в Ubuntu (64-разрядная версия) и Windows 7 (32-разрядная версия), используя один и тот же код, и он работает точно так же с теми же результатами. - person Zach; 12.05.2015