将多列合并为一列

Combining multiple columns into one

我有一个数据集如下:

`      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" 变量和值应该用换行符分隔。

UPDATE: 还有一种特殊情况:当一行根本没有值时。我想保留这些(见上下 GN == 19)。 variablevalue 在这种情况下应该只是空的。

`      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")

你可以试试(df 是你的data.frame):

变量名:

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

这里有一个 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 对数据进行分组
  • 过滤条件为:如果所有的Value条目都是空字符串,则检查行号是否为1(也就是说,return只有此类组的第一行)else(如果至少有一个或多个值条目 不是 空字符串) return 只有那些不为空的行
  • 然后,在每一列(分组列除外)上,将每组的所有唯一值汇总到一个字符串中,以 \n
  • 分隔