首页 文章

使用另一个数据框中的唯一值和分配给列的相应值创建具有列名的新数据框

提问于
浏览
3

我是R的新手,我很确定这很容易实现,但我无法弄清楚如何执行此操作 . 我已经尝试了使用for循环的split函数,但是无法弄清楚如何正确使用它 . 例如,这就是我原始数据框的样子:

dat <- data.frame(col1 = c(rep("red", 4), rep("blue", 3)), col2 = c(1, 3, 2, 4, 7, 8, 9))

 col1 col2
  red    1
  red    3
  red    2
  red    4
 blue    7
 blue    8
 blue    9

我想为col1中的每个唯一值创建新列,并将它在col2中的corressponding值分配给新数据框 . 这就是我想要的新数据框架:

red  blue
 1       7
 3       8
 2       9
 4      NA

我已经接近了一个接近我想要的列表结构,但我需要一个数据框来进行boxplot和dotplot结果 . 任何帮助都会得到满足 . 谢谢!

3 回答

  • 6

    我确信这是一个更有效的解决方案,但这里有一个选择

    dat <- data.frame(col1 = c(rep("red", 4), rep("blue", 3)), col2 = c(1, 3, 2, 4, 7, 8, 9))
    dat
    
      col1 col2
    1  red    1
    2  red    3
    3  red    2
    4  red    4
    5 blue    7
    6 blue    8
    7 blue    9    
    
    ust <- unstack(dat, form = col2 ~ col1)
    res <- data.frame(sapply(ust, '[', 1:max(unlist(lapply(ust, length)))))
    res
      blue red
    1    7   1
    2    8   3
    3    9   2
    4   NA   4
    

    编辑:如果您希望列顺序为红色,则为蓝色

    res[, c("red", "blue")]
      red blue
    1   1    7
    2   3    8
    3   2    9
    4   4   NA
    
  • 0

    这是一个Hadleyverse可能的解决方案

    library(tidyr)
    library(dplyr)
    dat %>%
      group_by(col1) %>%
      mutate(n = row_number()) %>%
      spread(col1, col2)
    # Source: local data frame [4 x 3]
    # 
    #   n blue red
    # 1 1    7   1
    # 2 2    8   3
    # 3 3    9   2
    # 4 4   NA   4
    

    或使用 data.table

    library(data.table)
    dcast(setDT(dat)[, indx := 1:.N, by = col1], indx ~ col1, value.var = "col2")
    #    indx blue red
    # 1:    1    7   1
    # 2:    2    8   3
    # 3:    3    9   2
    # 4:    4   NA   4
    
  • 3

    只是为了显示使用基础R *applycbind 的另一个选项

    # split the data into list using col1 column
    tmp.list   = lapply(split(dat, dat$col1), function(x) x$col2)
    
    # identify the length of the biggest list
    max.length = max(sapply(tmp.list, length))
    
    # combine the list elements, while filling NA for the missing values
    data.frame(do.call(cbind, 
      lapply(tmp.list, function(x) c(x, rep(NA, max.length - length(x))))
    ))
    
    #  blue red
    #1    7   1
    #2    8   3
    #3    9   2
    #4   NA   4
    

相关问题