Преобразование имени столбца (года) в переменные значения — Python, R

У меня есть CSV, который выглядит так:

                       1991       1992      1993       1991       1992      1993
VariableA  VariableB   VariableC  VariableC VariableC  VariableD  VariableD VariableD
     lm          mt         1          3          4            2        3         5

Итак, я хотел бы создать переменную с именем year и сделать следующее:

VariableA VariableB     Year   VariableC   VariableD 
 lm          mt         1991      1            2
 lm          mt         1992      3            3
 lm          mt         1993      4            5

В основном я работаю с пандами, которые я изучаю, но я не знаю, как правильно читать эти данные, а затем выполнять манипуляции. Если кто-то придумает решение на R, тоже было бы неплохо.

ИЗДАНИЕ:

Мой реальный фрейм данных относится к годам с 1991 по 2013 год, и есть больше переменных, которые имеют дубликаты. Я попробовал код inr R с пакетом splitstackshape, предложенным Ananda Mahto, но получаю сообщение об ошибке. Итак, в чем моя ошибка?

mydf <- read.csv("DatosCOMPUSTATfinal.csv", skip = 3, check.names = FALSE)

nombres <- names(mydf)[-c(1,2,3)]

nombres <- unique(nombres)

> nombres
 [1] "Employees"                  "Market Value-daily"        
 [3] "Market to book - daily"     "Total return"              
 [5] "Total assets"               "total stockholders' equity"
 [7] "Sales"                      "EBITDA"                    
 [9] "EBIT"                       "Pretax income"             
[11] "Income (loss)"             

> names(mydf[c(1,2,3)])
    [1] "Company name"            "employer identification"
    [3] "CUSIP"     

names(mydf)[-c(1,2,3)] <- paste(names(mydf)[-c(1,2,3)], 
                               c(1991:2013), sep = "_")


nv <- merged.stack(mydf, id.vars = names(mydf[c(1,2,3)]) , var.stubs = nombres , sep = "_" )

Затем я получаю сообщение об ошибке:

Error in if (ncol(x) == 1L) { : argument is of length zero

ВЕРСИЯ 2:

Я пробовал этот код с функцией изменения формы, но получаю сообщение "память исчерпана". Я не знаю, почему, потому что фрейм данных просто меняет свое направление, а его размер меньше 15 МБ. Почему это происходит и как с этим бороться?

newmydf <- reshape(mydf, direction = "long", idvar = 1:3, varying = 4:ncol(mydf), sep = "_")
Error: memory exhausted (limit reached?)

person CreamStat    schedule 21.10.2014    source источник
comment
У вас действительно есть файл csv, разделенный запятыми, или данные точно такие, как вы разместили, просто разделенные пробелами?   -  person thelatemail    schedule 21.10.2014
comment
У меня есть CSV с такой же структурой. Годы на самом деле с 1991 по 2013.   -  person CreamStat    schedule 21.10.2014
comment
Итак, чтобы уточнить, в mydf 11 * 23 (253) столбца? Позвольте мне посмотреть, смогу ли я воссоздать ошибку.   -  person A5C1D2H2I1M1N2O1R2T1    schedule 22.10.2014
comment
253 в var.stubs плюс 3 в id.vars, всего 256.   -  person CreamStat    schedule 22.10.2014


Ответы (2)


В R одним из способов может быть чтение csv, пропуская первую строку, добавляя ее обратно как часть ваших имен переменных, а затем используя reshape для получения желаемого вывода.

Попробуйте что-то вроде следующего:

mydf <- read.csv("yourfile.csv", skip = 1, check.names = FALSE)
names(mydf)[-c(1, 2)] <- paste(names(mydf)[-c(1, 2)], 
                               c(1991, 1992, 1993), sep = "_")
reshape(mydf, direction = "long", idvar = 1:2, 
        varying = 3:ncol(mydf), sep = "_")
#            VariableA VariableB time VariableC VariableD
# lm.mt.1991        lm        mt 1991         1         2
# lm.mt.1992        lm        mt 1992         3         3
# lm.mt.1993        lm        mt 1993         4         5

После шага переименования, если reshape() для вас слишком медленный, попробуйте merged.stack из моего пакета "splitstackshape":

library(splitstackshape)
merged.stack(mydf, var.stubs = c("VariableC", "VariableD"), sep = "_")
#    VariableA VariableB .time_1 VariableC VariableD
# 1:        lm        mt    1991         1         2
# 2:        lm        mt    1992         3         3
# 3:        lm        mt    1993         4         5
person A5C1D2H2I1M1N2O1R2T1    schedule 21.10.2014

Другой способ в R — использовать dplyr/tidyr (что будет быстрее для больших наборов данных) после того, как вы прочитаете набор данных с помощью read.csv, как указано в сообщении @Ananda Mahto.

 library(dplyr)
 library(tidyr)

  mydf %>% 
       gather(Var, Val, matches("[0-9]+$")) %>% 
       separate(Var, c("Var", "Year")) %>%
       spread(Var, Val)

  #  VariableA VariableB Year VariableC VariableD
  #1        lm        mt 1991         1         2
  #2        lm        mt 1992         3         3
  #3        lm        mt 1993         4         5

данные

 mydf <- structure(list(VariableA = structure(1L, .Label = "lm", class = "factor"), 
VariableB = structure(1L, .Label = "mt", class = "factor"), 
VariableC_1991 = 1L, VariableC_1992 = 3L, VariableC_1993 = 4L, 
VariableD_1991 = 2L, VariableD_1992 = 3L, VariableD_1993 = 5L), .Names = c("VariableA", 
"VariableB", "VariableC_1991", "VariableC_1992", "VariableC_1993", 
"VariableD_1991", "VariableD_1992", "VariableD_1993"), class = "data.frame", row.names = c(NA, 
-1L))
person akrun    schedule 21.10.2014
comment
Я могу быть предвзятым, но я предпочитаю merged.stack здесь :-) - person A5C1D2H2I1M1N2O1R2T1; 21.10.2014