【问题标题】:How do I merge column values into a column of vectors based on unique row values?如何根据唯一的行值将列值合并到向量列中?
【发布时间】:2020-12-26 07:59:25
【问题描述】:

我是 R 新手,因此非常感谢您帮助了解正在发生的事情! 我有一个非常大的数据框,结构如下:

变量 1 变量 2
(chr) (int)
一、1
一、二
A , 3
B , 4
B , 5
C , 6
C , 7
C , 8
C , 9
...

我想创建一个新的数据框,将 Var 1 分类值组合在一起,并将所有相应的整数 Var2 值组合成数值向量

我希望它看起来像: Var1 Var2_Combined
(chr) (int)
A , 向量[1, 2, 3]
B , 向量[4, 5]
C , 向量[6, 7, 8, 9]

因为数据集很大,我不想手动分配每个向量,我想通过一个函数来完成。我尝试了以下方法,但没有成功。

1.转换为字符串

write.csv(aggregate(df$Var2 ~ df$Var1, FUN = toString), file = "Test_file")    

但我无法使用 as.numeric() 或 as.integer() 或任何这些类型的命令将字符串转换回可用的数字。

2。连接
我试图用 c() 来做到这一点

write.csv(aggregate(df$Var2 ~ df$Var1, FUN = c), file = "Test_file")    

虽然它将所有 Var2 值与 Var1 中的唯一值相匹配,但它创建了一堆新列,而不是将这些值组合成向量的列:

Var1 Var2 Var3 Var4 Var5
(chr) (int) (int) (int)
A , 1 , 2 , 3
B , 1 , 2 , 3

3。一个 for 循环

我尝试使用 unique() 过滤器和一个“for”循环,但它只是返回了不可用的数字

Var1_Unique <- unique(df$Var1)    
Var2_Combined <- numeric(length = length(Var1_Unique))    

for (i in seq(1, length(Var1_Unique))) {         
   Var2_Combined[i] <- df %>% filter(Var2 == Var1_Unique[i]) 
   }   

我现在只连接了 dplyr。

谢谢

【问题讨论】:

    标签: r


    【解决方案1】:

    有两种选择:

    1.将数据存储在列表中。

    A.使用基础 R:

    df1 <- aggregate(Var2~Var1, df, list)
    df1
    
    #  Var1       Var2
    #1    A    1, 2, 3
    #2    B       4, 5
    #3    C 6, 7, 8, 9
    
    str(df1)
    #'data.frame':  3 obs. of  2 variables:
    # $ Var1: chr  "A" "B" "C"
    # $ Var2:List of 3
    #  ..$ : int  1 2 3
    #  ..$ : int  4 5
    #  ..$ : int  6 7 8 9
    

    现在将数据恢复为原始数据。

    df2 <- transform(df1[rep(1:nrow(df1), lengths(df1$Var2)), ], 
                     Var2 = unlist(df1$Var2))
    str(df2)
    #'data.frame':  9 obs. of  2 variables:
    # $ Var1: chr  "A" "A" "A" "B" ...
    # $ Var2: int  1 2 3 4 5 6 7 8 9
    

    B.使用tidyverse

    library(dplyr)
    library(tidyr)
    df1 <- df %>% group_by(Var1) %>% summarise(Var2 = list(Var2))
    df2 <- df1 %>% unnest(Var2)
    

    2。将数据存储为字符串。

    A.使用基础 R

    df1 <- aggregate(Var2~Var1, df, toString)
    str(df1)
    #'data.frame':  3 obs. of  2 variables:
    # $ Var1: chr  "A" "B" "C"
    # $ Var2: chr  "1, 2, 3" "4, 5" "6, 7, 8, 9"
    

    将其恢复为原始格式。

    tmp <- strsplit(df1$Var2, ', ')
    df2 <- transform(df1[rep(1:nrow(df1), lengths(tmp)),], 
                     Var2 = as.numeric(unlist(tmp)))
    str(df2)
    #'data.frame':  9 obs. of  2 variables:
    # $ Var1: chr  "A" "A" "A" "B" ...
    # $ Var2: num  1 2 3 4 5 6 7 8 9
    

    B.使用tidyverse

    df1 <- df %>% group_by(Var1) %>% summarise(Var2 = toString(Var2))
    df2 <- df1 %>% separate_rows(Var2, sep = ', ', convert = TRUE)
    

    如果您只想将数据保留在 R 中,则可以使用这两个选项。如果您想将 df1 的中间结果写入 csv,则不能使用选项 1,因为 write.csv 无法将列表列写入 csv,在这种情况下您需要使用选项 2。

    【讨论】:

    • 非常感谢,这太完美了!你的答案 1.A.正是我想要的。创建一个列表是如此容易,我很尴尬,我没有想到它。再次感谢您!
    猜你喜欢
    • 1970-01-01
    • 2020-03-16
    • 2022-01-13
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多