将多个列合并为一个

3

我有一个如下所示的数据集:

`      GN      Datum                      Land AG..GKV. MTCR..GKV. NSGI..GKV. NSGII..GKV. WA..GKV. ML..GKV.   Wert
8  11693 2012-01-05                     Kenia                                              5A001f          159700
9  11710 2012-01-05                    Indien 1C350.43                                                      18752
10 11749 2012-01-05 Taiwan, Provinz von China  2B350g2                                                      24000
11 11750 2012-01-05                    Indien                                    2B201a1  2B001b2          370296
12 11751 2012-01-05                   Serbien                                     2B201a                     7200
13 11752 2012-01-05                    Indien                                                           4c   6037
14 11753 2012-01-05                  Rumänien                                              2B001d            7830
15 11755 2012-01-06                     China                                    2B201a1                   215987
16 11756 2012-01-06                     China                                    2B201a1                   234736
17 11757 2012-01-06                 Brasilien                                      2B231                    69900
18 11758 2012-01-06                 Brasilien                                      2B231                   139800
19 11788 2012-01-07                 Kongo                                                                  139800

GN是唯一的ID。正如您所看到的,对于每一行,变量AG..GKV.ML..GKV最多只保持一个值,除非GN == 11750

我想将这些变量合并成一个,但仍然知道原始变量名,就像这样:

`      GN      Datum                      Land variable value    Wert
8  11693 2012-01-05                     Kenia  WA..GKV. 5A001f   159700    
9  11710 2012-01-05                    Indien  AG..GKV. 1C350.43 18752
...

如果每行有两个值,例如 GN == 11750,应该像这样显示:
`      GN      Datum       Land   variable                value           Wert
11  11750 2012-01-05     Indien  NSGII..GKV.\nWA..GKV.    2B201a1\n2B201a 370296   

即,"double"变量和值应该由一个新的行分隔符分开。
更新:还有一种特殊情况:当一行中没有任何值时。我想保留这些(见上面和下面的GN == 19)。在这种情况下,"variable"和"value"应该为空。
`      GN      Datum       Land   variable                value           Wert
19  11788 2012-01-07      Kongo                                           370296   

我不知道如何实现这一点,已经尝试了reshape包,但可能太过于R新手。
这是一个dput(与上面的案例不同,但具有三种结果类型):
    structure(list(GN = c(11789L, 11790L, 11791L, 11793L, 11794L, 
11795L, 11796L), Datum = structure(c(15355, 15355, 15355, 15355, 
15355, 15356, 15356), class = "Date"), Land = c("China", "Israel", 
"Pakistan", "Iran, Islamische Republik", "Hong Kong", "Südafrika", 
"Lettland"), AG..GKV. = c("2B350d4", "", "", "", "", "", ""), 
    MTCR..GKV. = c("", "", "", "", "", "", ""), NSGI..GKV. = c("", 
    "", "", "", "", "", ""), NSGII..GKV. = c("", "", "", "", 
    "", "", "2B201a1"), WA..GKV. = c("", "7A002a+b", "", "", 
    "3A001a2c", "6A003b4", "2B001b2"), ML..GKV. = c("", "", "", 
    "", "", "", ""), Wert = c(63720, 25672, 1608000, 10738, 202500, 
    13500, 374873)), .Names = c("GN", "Datum", "Land", "AG..GKV.", 
"MTCR..GKV.", "NSGI..GKV.", "NSGII..GKV.", "WA..GKV.", "ML..GKV.", 
"Wert"), row.names = 49:55, class = "data.frame")
2个回答

2
您可以尝试以下方法(其中df是您的数据框):
变量名称:
df$variable<-apply(df[,4:9],1,function(x){paste(colnames(df[,4:9])[which(x!="")],collapse="\n")})

数值:

df$value<-apply(df[,4:9],1,function(x){paste(x[which(x!="")],collapse="\n")})

最后,删除原始列并重新组织:
df<-df[,c(1:3,11:12,10)]

输出:

> df
      GN      Datum                      Land              variable            value   Wert
8  11693 2012-01-05                     Kenia              WA..GKV.           5A001f 159700
9  11710 2012-01-05                    Indien              AG..GKV.         1C350.43  18752
10 11749 2012-01-05 Taiwan, Provinz von China              AG..GKV.          2B350g2  24000
11 11750 2012-01-05                    Indien NSGII..GKV.\nWA..GKV. 2B201a1\n2B001b2 370296
12 11751 2012-01-05                   Serbien           NSGII..GKV.           2B201a   7200
13 11752 2012-01-05                    Indien              ML..GKV.               4c   6037
14 11753 2012-01-05                  Rumänien              WA..GKV.           2B001d   7830
15 11755 2012-01-06                     China           NSGII..GKV.          2B201a1 215987
16 11756 2012-01-06                     China           NSGII..GKV.          2B201a1 234736
17 11757 2012-01-06                 Brasilien           NSGII..GKV.            2B231  69900
18 11758 2012-01-06                 Brasilien           NSGII..GKV.            2B231 139800

2

以下是使用tidyr和dplyr的选项:

library(dplyr)
library(tidyr)
DF %>% gather(Variable, Value, AG..GKV.:ML..GKV.) %>% 
    filter(Value != "") %>% group_by(GN, Datum, Land) %>% 
    summarise_each(funs(paste(unique(.), collapse = "\n")))

#Source: local data frame [11 x 6]
#Groups: GN, Datum
#
#      GN      Datum                      Land   Wert              Variable            Value
#1  11693 2012-01-05                     Kenia 159700              WA..GKV.           5A001f
#2  11710 2012-01-05                    Indien  18752              AG..GKV.         1C350.43
#3  11749 2012-01-05 Taiwan, Provinz von China  24000              AG..GKV.          2B350g2
#4  11750 2012-01-05                    Indien 370296 NSGII..GKV.\nWA..GKV. 2B201a1\n2B001b2
#5  11751 2012-01-05                   Serbien   7200           NSGII..GKV.           2B201a
#6  11752 2012-01-05                    Indien   6037              ML..GKV.               4c
#7  11753 2012-01-05                  Rumänien   7830              WA..GKV.           2B001d
#8  11755 2012-01-06                     China 215987           NSGII..GKV.          2B201a1
#9  11756 2012-01-06                     China 234736           NSGII..GKV.          2B201a1
#10 11757 2012-01-06                 Brasilien  69900           NSGII..GKV.            2B231
#11 11758 2012-01-06                 Brasilien 139800           NSGII..GKV.            2B231

请注意,只有在它们是唯一的情况下,这将创建由“\n”分隔的多个条目,我假设这是您想要做的。

OP评论后编辑:

对于您的特殊情况,请尝试以下代码:

DF %>% gather(Variable, Value, AG..GKV.:ML..GKV.) %>% 
    group_by(GN, Datum, Land) %>% filter(if(all(Value == "")) row_number() == 1 else Value != "") %>% 
    summarise_each(funs(paste(unique(.), collapse = "\n")))

解释:

  • gather将数据从宽格式转换为长格式(使用列AG..GKV.到ML..GKV.)
  • 然后我们按GN、Datum和Land分组数据
  • 筛选条件为:如果所有值条目都是空字符串,则检查行号是否为1(这意味着只返回这些组的第一行),否则(如果至少有一个或多个值条目不是空字符串)则只返回那些非空行
  • 然后,在每个列上 - 除了分组列 - 对每个组中的所有唯一值进行汇总,用\n分隔成单个字符串

谢谢。tidyr 依赖于 dplyr 吗?或者说哪个库负责代码的哪一部分? - grssnbchr
好的。您的解决方案在执行时给出了 Error in filter(., Value != "") : object 'Value' not found 的错误信息。为什么会这样? - grssnbchr
没关系,我没有显式加载 dplyr,我以为它会随着 tidyr 一起加载。现在它可以工作了。 - grssnbchr
我添加了一个特殊情况,一开始忘记了,请查看我的更新问题,也许您可以使用 dplyrtidyr 来解决这个问题。问题是 filter(Value != "") 对这种情况和“正常”情况没有区别。 - grssnbchr
1
@wnstnsmth,你是不是从我的答案中复制粘贴了整个代码?请注意,filter语句现在是在group_by之后。 - talat
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接