如何从数据框中提取csv列并将其与现有数据框组合

时间:2019-02-11 10:20:30

标签: r csv read.table read.csv

我有一个数据框,其中包含来自广泛格式的调查表中的数据。但是一列包含压缩的实验数据,其中包含长格式的csv格式数据(作为字符串)。所以我想撤消这种压缩并恢复完整的表格数据集。应该重复使用宽格式中的值来填充添加的行。

这将是我的数据框:

    df_wide <- data.frame(v1 = c("1", "2", "3"), 
                  v2 = c("sender, correct, \n1, y, \n2, y,", 
                      "sender, correct, \n2, n, \n1, n,", 
                      "sender, correct, \n1, n, \n2, y,"))
    colnames(df_wide) <- c("ID", "csvcolumn")
    df_wide$csvcolumn <- as.character(df_wide$csvcolumn)

> df_wide
>  ID                        csvcolumn
>1  1 sender, correct, \n1, y, \n2, y,
>2  2 sender, correct, \n2, n, \n1, n,
>3  3 sender, correct, \n1, n, \n2, y,

我希望它看起来像这样:

> df_long
  ID  sender  correct
   1     1      y
   1     2      y
   2     2      n
   2     1      n
   3     1      n
   3     2      y

我能够读取csv列,并使用

将其另存为新数据框
  

df2 <-read.table(text = df_wide $ csvcolumn,sep =“,”,header = TRUE,allowEscapes = TRUE)

但是很明显,这不包括宽格式数据,我也不知道哪些数据属于哪个ID。

我希望这是可以解决的,感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我会质疑这里使用的输入。可能在Excel中优化到对R更有意义的输入。但是,并非总是可能...

要清理此问题,请首先删除每个csvcolumn不需要的标头,然后分割成\n个字符(需要tidyverse!)

library(tidyverse)    
df_n <- df_wide %>% dplyr::mutate(n = gsub("sender, correct, \n", 
                                    "", 
                                    csvcolumn)) %>% 
                    dplyr::select(1,3) %>%
                    tidyr::separate(data=., 
                                    col="n", 
                                    sep="\n",
                                    into=c("s1","c1"))

然后使用与您的read.csv技巧类似的方法,但使用read_csv

df_list <- lapply(df_n, function(f){
                          read_csv(as.vector(f), col_names=F)
                        })

然后,您可以调用rbind来获取调查表数据,然后通过总行除以ID的长度来ID

qdat <- do.call(rbind,df_list[2:length(df_list)]) %>% 
        dplyr::select(1,2) %>% 
        as_tibble() 
df_long <- qdat %>%
           dplyr::mutate(ID = rep(unlist(df_list[[1]]), 
                                  dim(qdat)[1]/dim(df_list[[1]])[1])) %>%
           dplyr::select(ID, sender="X1", correct = "X2")

df_long
# A tibble: 6 x 3
     ID sender correct
  <dbl>  <dbl> <chr>
1     1      1 y
2     2      2 n
3     3      1 n
4     1      2 y
5     2      1 n
6     3      2 y