【问题标题】:How to "reshape" this data into a useable format?如何将这些数据“重塑”为可用的格式?
【发布时间】:2018-01-27 17:06:55
【问题描述】:

我有这个数据集,它的格式很奇怪。

看起来像这样:

          1971 1971 1971 1972 1972 1972
          var1 var2 var3 var1 var2 var3
person1     37    2    1   65    5    3   
person2     65    2    1  123    3    1   
person3     23    3    1   13    6    2   

我想知道是否有任何简单的方法可以将这些数据变成如下所示的内容:

         year  var1 var2 var3
person1  1971    37    2    1   
person1  1972    65    5    3   
person2  1971    65    2    1 
person2  1972   123    3    1
person3  1971    23    3    1
person3  1972    13    6    2

我认为我想做的是反向重塑数据或其他东西。我已经研究过融化、投射和转置,但我没有得到任何有用的结果。

【问题讨论】:

  • data.frame中的years和var1-3是如何存储的?
  • 所以这就是我在 excel 中打开 csv 的样子。当我将其作为数据框 Var1 读入时,var2 等只是第一行中的条目,变量是 1971.1,1971.2 等等
  • 您的数据存储在哪个格式文件中?单独阅读第 1 行可能是一个想法
  • csv 格式
  • 你能给出你用来读取输入文件的函数吗?还有原始文件

标签: r reshape transpose


【解决方案1】:

这是我试图找出您需要什么的尝试。如果某些内容不准确,请根据您的意愿进行修改。我使用了 3 个库,但不用担心。在 R 中,这些经常结合在一起,无论如何都很好地了解未来。我本可以用基本的 R 编写代码,但这意味着代码要长得多

input.csv

,1971,1971,1971,1972,1972,1972
,var1,var2,var3,var1,var2,var3
person1,37,2,1,65,5,3
person2,65,2,1,123,3,1
person3,23,3,1,13,6,2

修改表示的代码

library(reshape2)
library(tidyr)
library(dplyr)

input = read.table("input.csv", sep=",", na.strings="", header=T)[-1,]
converted_input = input %>%
  tidyr::gather(year, value, -X) %>%
  dplyr::mutate(
    var=paste0("var", as.numeric(gsub("^X.*", "0", gsub(".*\\.([0-9])$", "\\1", year)))+1),
    year=gsub("X([^.]+).*", "\\1", year)) %>%
  reshape2::dcast(X + year ~ var, value.var="value") %>%
  dplyr::rename(person=X)

print(converted_input)

最终结果

 person year var1 var2 var3
person1 1971   37    2    1
person1 1972   65    5    3
person2 1971   65    2    1
person2 1972  123    3    1
person3 1971   23    3    1
person3 1972   13    6    2

【讨论】:

    【解决方案2】:

    这是一种难以使用的格式,因为原始文件中的列标题信息来自两行。我的方法是读取除第一行以外的所有数据,然后再读取第一行进行数据操作。

    第一步:读取除第一行以外的数据

    dat <- read.table(text = "         1971 1971 1971 1972 1972 1972
              var1 var2 var3 var1 var2 var3
                      person1     37    2    1   65    5    3   
                      person2     65    2    1  123    3    1   
                      person3     23    3    1   13    6    2",
                      header = TRUE, stringsAsFactors = FALSE, skip = 1)
    dat
    #         var1 var2 var3 var1.1 var2.1 var3.1
    # person1   37    2    1     65      5      3
    # person2   65    2    1    123      3      1
    # person3   23    3    1     13      6      2
    

    第 2 步:将第一行作为向量读取

    Year <- read.table(text = "         1971 1971 1971 1972 1972 1972
              var1 var2 var3 var1 var2 var3
                       person1     37    2    1   65    5    3   
                       person2     65    2    1  123    3    1   
                       person3     23    3    1   13    6    2",
                       header = FALSE, stringsAsFactors = FALSE, nrows = 1)
    
    # Convert Year to a vector
    Year <- unlist(Year)
    Year
    #   V1   V2   V3   V4   V5   V6 
    # 1971 1971 1971 1972 1972 1972
    

    第三步:合并头部信息

    library(tidyverse)
    
    # Rename the dat dat data frame
    dat2 <- dat %>%
      setNames(paste(names(.), Year, sep = "_")) %>%
      setNames(sub("\\.\\d+", "", names(.)))
    dat2
    #         var1_1971 var2_1971 var3_1971 var1_1972 var2_1972 var3_1972
    # person1        37         2         1        65         5         3
    # person2        65         2         1       123         3         1
    # person3        23         3         1        13         6         2
    

    现在dat2 是我们可以使用的格式。

    第 4 步:重塑数据框

    # Reshape the dtaa frame
    dat3 <- dat2 %>%
      rownames_to_column(var = "Person") %>%
      gather(Variable, Value, -Person) %>%
      separate(Variable, into = c("Var", "Year")) %>%
      spread(Var, Value)
    dat3
    #    Person Year var1 var2 var3
    # 1 person1 1971   37    2    1
    # 2 person1 1972   65    5    3
    # 3 person2 1971   65    2    1
    # 4 person2 1972  123    3    1
    # 5 person3 1971   23    3    1
    # 6 person3 1972   13    6    2
    

    dat3 是最终输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-11
      • 2022-01-11
      相关资源
      最近更新 更多