Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 从长到宽,具有自动虚拟创建和多个值列_R_Dataframe_Dplyr_Tidyr_Tidyverse - Fatal编程技术网

R 从长到宽,具有自动虚拟创建和多个值列

R 从长到宽,具有自动虚拟创建和多个值列,r,dataframe,dplyr,tidyr,tidyverse,R,Dataframe,Dplyr,Tidyr,Tidyverse,我坐在一个数据框前面,看起来像这样: country year Indicator a b c 48996 US 2003 var1 NA NA NA 16953 FR 1988 var2 NA 10664.920 NA 22973 FR 1943 var3 NA 5774.334 NA

我坐在一个数据框前面,看起来像这样:

      country year Indicator         a         b        c
48996      US 2003      var1        NA        NA       NA
16953      FR 1988      var2        NA 10664.920       NA
22973      FR 1943      var3        NA  5774.334       NA
8760       CN 1995      var4  8804.565        NA 12750.31
47795      US 2012      var5        NA        NA       NA
30033      GB 1969      var6        NA 29631.362       NA
25796      FR 1921      var7        NA 14004.520       NA
39534      NL 1941      var8        NA        NA       NA
42255      NZ 1969      var8        NA        NA       NA
7249       CN 1995      var9 50635.862        NA 75260.56
我想做的基本上是一个从长到宽的转换,使用
指示符
作为关键变量。我通常使用
tidyr
包中的
spread()
。但是,不幸的是,
spread()
不接受多个值列(在本例中,
a
b
c
),并且它没有完全实现我想要实现的目标:

  • 指示器的条目设置为新列
  • 将国家/年度组合保留为行
  • a
    b
    c
  • 为每个“旧”值列名称(即, b、 (c)
  • 所以最后,中国人对我的例子的观察应该是

    country year var1 [...] var4       [...]   var9       dummy.a dummy.b dummy.c 
    CN      1995 NA         8804.565           50635.862        1       0       0
    CN      1995 NA         12750.31           75260.56         0       0       1
    
    由于我的原始数据帧是58.162x119,我希望不包含大量手动工作的内容:-)

    我希望我清楚地知道我想要实现什么。谢谢你的帮助


    可以使用以下代码再现上述数据帧:

    structure(list(country = c("US", "FR", "FR", "CN", "US", "GB", 
    "FR", "NL", "NZ", "CN"), year = c(2003L, 1988L, 1943L, 1995L, 
    2012L, 1969L, 1921L, 1941L, 1969L, 1995L), Indicator = structure(c(1L, 
    2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 9L), .Label = c("var1", "var2", 
    "var3", "var4", "var5", "var6", "var7", "var8", "var9", "var10", 
    "var11", "var12", "var13", "var14", "var15", "var16", "var17", 
    "var18"), class = "factor"), a = c(NA, NA, NA, 8804.56480733, 
    NA, NA, NA, NA, NA, 50635.8621327), b = c(NA, 10664.9199219, 
    5774.33398438, NA, NA, 29631.3618614, 14004.5195312, NA, NA, 
    NA), c = c(NA, NA, NA, 12750.3056855, NA, NA, NA, NA, NA, 75260.555946
    )), .Names = c("country", "year", "Indicator", "a", "b", "c"), row.names = c(48996L, 
    16953L, 22973L, 8760L, 47795L, 30033L, 25796L, 39534L, 42255L, 
    7249L), class = "data.frame")
    
    以下是我的解决方案:

    require(tidyr)
    mydf <- structure(list(country = c("US", "FR", "FR", "CN", "US", "GB", 
        "FR", "NL", "NZ", "CN"), year = c(2003L, 1988L, 1943L, 1995L, 
        2012L, 1969L, 1921L, 1941L, 1969L, 1995L), Indicator = structure(c(1L, 
        2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 9L), .Label = c("var1", "var2", 
        "var3", "var4", "var5", "var6", "var7", "var8", "var9", "var10", 
        "var11", "var12", "var13", "var14", "var15", "var16", "var17", 
        "var18"), class = "factor"), a = c(NA, NA, NA, 8804.56480733, 
        NA, NA, NA, NA, NA, 50635.8621327), b = c(NA, 10664.9199219, 
        5774.33398438, NA, NA, 29631.3618614, 14004.5195312, NA, NA, 
        NA), c = c(NA, NA, NA, 12750.3056855, NA, NA, NA, NA, NA, 75260.555946
        )), .Names = c("country", "year", "Indicator", "a", "b", "c"), row.names = c(48996L, 
        16953L, 22973L, 8760L, 47795L, 30033L, 25796L, 39534L, 42255L, 
        7249L), class = "data.frame")
    
    mydf %>% gather(key=newIndicator,value=values, a,b,c) %>% filter(!is.na(values)) %>% spread(key=Indicator,values) %>% mutate(indicatorValues=1) %>% spread(newIndicator,indicatorValues,fill=0)
    
    以下是我的解决方案:

    require(tidyr)
    mydf <- structure(list(country = c("US", "FR", "FR", "CN", "US", "GB", 
        "FR", "NL", "NZ", "CN"), year = c(2003L, 1988L, 1943L, 1995L, 
        2012L, 1969L, 1921L, 1941L, 1969L, 1995L), Indicator = structure(c(1L, 
        2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 9L), .Label = c("var1", "var2", 
        "var3", "var4", "var5", "var6", "var7", "var8", "var9", "var10", 
        "var11", "var12", "var13", "var14", "var15", "var16", "var17", 
        "var18"), class = "factor"), a = c(NA, NA, NA, 8804.56480733, 
        NA, NA, NA, NA, NA, 50635.8621327), b = c(NA, 10664.9199219, 
        5774.33398438, NA, NA, 29631.3618614, 14004.5195312, NA, NA, 
        NA), c = c(NA, NA, NA, 12750.3056855, NA, NA, NA, NA, NA, 75260.555946
        )), .Names = c("country", "year", "Indicator", "a", "b", "c"), row.names = c(48996L, 
        16953L, 22973L, 8760L, 47795L, 30033L, 25796L, 39534L, 42255L, 
        7249L), class = "data.frame")
    
    mydf %>% gather(key=newIndicator,value=values, a,b,c) %>% filter(!is.na(values)) %>% spread(key=Indicator,values) %>% mutate(indicatorValues=1) %>% spread(newIndicator,indicatorValues,fill=0)
    

    dt
    将是您的原始数据
    dt2
    是最终输出

    dt2 <- dt %>%
      gather(Parameter, Value, a:c) %>%
      spread(Indicator, Value) %>%
      mutate(Data = ifelse(rowSums(is.na(.[, paste0("var", 1:9)])) != 9, 1, 0)) %>%
      filter(Data != 0) %>%
      spread(Parameter, Data, fill = 0) %>%
      rename(dummy.a = a, dummy.b = b, dummy.c = c)
    
    dt2%
    聚集(参数,值,a:c)%>%
    排列(指示器,值)%>%
    突变(数据=ifelse(行和(is.na([粘贴0(“var”,1:9)])!=9,1,0))%>%
    过滤器(数据!=0)%>%
    排列(参数、数据、填充=0)%>%
    重命名(dummy.a=a,dummy.b=b,dummy.c=c)
    
    dt
    将是您的原始数据
    dt2
    是最终输出

    dt2 <- dt %>%
      gather(Parameter, Value, a:c) %>%
      spread(Indicator, Value) %>%
      mutate(Data = ifelse(rowSums(is.na(.[, paste0("var", 1:9)])) != 9, 1, 0)) %>%
      filter(Data != 0) %>%
      spread(Parameter, Data, fill = 0) %>%
      rename(dummy.a = a, dummy.b = b, dummy.c = c)
    
    dt2%
    聚集(参数,值,a:c)%>%
    排列(指示器,值)%>%
    突变(数据=ifelse(行和(is.na([粘贴0(“var”,1:9)])!=9,1,0))%>%
    过滤器(数据!=0)%>%
    排列(参数、数据、填充=0)%>%
    重命名(dummy.a=a,dummy.b=b,dummy.c=c)
    
    Imo,这是一种非常糟糕的数据格式,但您可以像
    library(data.table)一样到达那里;melt(setDT(DF,keep.rownames=TRUE),id=c(“rn”,“country”,“year”,“Indicator”)[!is.na(value),dcast(.SD,country+year+variable~Indicator)][,dcast(.SD,…~variable,value.var=“variable”,fun=length)]
    我认为基于输入的预期不正确。例如,“1983年”的Var4应为8804.565和12750.306。您使用
    dput
    提供的数据集与您的示例不同。例如,在第4行中,是1983年还是1995年?我的错,修复了它。我确实手动更改了一年,以便更清楚地了解我想要实现的目标,但忘记在示例代码中更改它。很抱歉感谢更新的数据集。您能解释一下为什么在虚拟变量
    a到c
    中,第一行
    CN
    1,0,0
    ,第二行是
    0,0,1
    ?因为基于您的原始数据帧,
    a
    c
    都有这两行的值。依我看,这是一种非常糟糕的数据格式,但您可以像
    库(data.table)一样到达那里;melt(setDT(DF,keep.rownames=TRUE),id=c(“rn”,“country”,“year”,“Indicator”)[!is.na(value),dcast(.SD,country+year+variable~Indicator)][,dcast(.SD,…~variable,value.var=“variable”,fun=length)]
    我认为基于输入的预期不正确。例如,“1983年”的Var4应为8804.565和12750.306。您使用
    dput
    提供的数据集与您的示例不同。例如,在第4行中,是1983年还是1995年?我的错,修复了它。我确实手动更改了一年,以便更清楚地了解我想要实现的目标,但忘记在示例代码中更改它。很抱歉感谢更新的数据集。您能解释一下为什么在虚拟变量
    a到c
    中,第一行
    CN
    1,0,0
    ,第二行是
    0,0,1
    ?因为基于原始数据帧,
    a
    c
    都有这两行的值。