Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 创建数据帧,基于列表的第一个元素进行匹配_R_List_Dataframe_Match_Data.table - Fatal编程技术网

R 创建数据帧,基于列表的第一个元素进行匹配

R 创建数据帧,基于列表的第一个元素进行匹配,r,list,dataframe,match,data.table,R,List,Dataframe,Match,Data.table,我想基于列表的第一个元素创建一个数据框。具体来说,我有 一个包含变量的向量(名称1) 一个包含两个变量(一些变量1和值)的列表 最终产品应该是一个带有“names1”的data.frame,其中包含的行数与匹配的案例数相同 如果特定列表和向量之间不匹配,则应为NA 值也可以是因子或字符串 names1 <- c("a", "b", "c") dat1 <- data.frame(names1 =c("a", "b", "c", "f"),values= c("val1", 13, 1

我想基于列表的第一个元素创建一个数据框。具体来说,我有
  • 一个包含变量的向量(名称1)
  • 一个包含两个变量(一些变量1和值)的列表
  • 最终产品应该是一个带有“names1”的data.frame,其中包含的行数与匹配的案例数相同
  • 如果特定列表和向量之间不匹配,则应为NA
  • 值也可以是因子或字符串

    names1 <- c("a", "b", "c")
    dat1 <- data.frame(names1 =c("a", "b", "c", "f"),values= c("val1", 13, 11, 0))
       dat1$values <- as.factor(dat1$values)
    dat2 <- data.frame(names1 =c("a", "b", "x"),values= c(12, 10, 2))
       dat2$values <- as.factor(dat2$values)
    list1 <- list(dat1, dat2)
    

    一个选项是循环通过
    列表
    ('list1'),
    过滤器
    基于'names'向量的'names'列,将其转换为单个数据集,同时创建具有
    .id
    排列
    的标识列,从'long'到'wide',并删除'grp'列

    library(tidyverse)
    map_df(list1, ~   .x %>% 
                         filter(names %in% !! names), .id = 'grp') %>%           
          spread(names, values) %>% 
          select(-grp)   
    #      a     b     c    
    #1    25    13    11
    #2    12    10    NA
    

    或者另一个选项是将数据集与
    bind_rows
    绑定在一起,创建一个分组id“grp”来指定
    列表
    元素,
    通过只选择与“name”
    向量相匹配的“names”列以及从“long”到“wide”的
    排列来过滤行

    bind_rows(list1, .id = 'grp') %>%
       filter(names %in% !! names) %>% 
       spread(names, values)
    
    注意:最好不要使用保留关键字来指定对象名称(
    名称
    )。此外,为了避免混淆,对象应该与dataframe对象的列名不同


    也可以仅使用
    base R
    完成此操作。使用
    映射
    rbind
    列表
    元素添加到单个数据集,
    子集
    行创建组标识符,方法是仅保留“名称”
    向量
    中的值,并将
    形状从“长”改为“宽”

    df1 <- subset(do.call(rbind, Map(cbind, list1, 
              ind = seq_along(list1))), names %in% .GlobalEnv$names)   
    reshape(df1, idvar = 'ind', direction = 'wide', timevar = 'names')[-1]
    

    df1基本R和
    dplyr的混合体
    。对于每个列表元素,我们创建一个包含1行的数据框。使用
    dplyr
    rbind\u列表
    行将它们绑定在一起,然后使用
    名称
    只对需要的列进行子集划分

    library(dplyr)
    
    rbind_list(lapply(list1, function(x) 
            setNames(data.frame(t(x$values)), x$names)))[names]
    
    #     a     b     c
    #   <dbl> <dbl> <dbl>
    #1    25    13    11
    #2    12    10    NA
    
    库(dplyr)
    rbind_列表(lappy)(列表1,函数(x)
    集合名(data.frame(t(x$value)),x$names))[名称]
    #a、b、c
    #     
    #1    25    13    11
    #2 12 10 NA
    
    没有子集的输出如下所示

    rbind_list(lapply(list1, function(x) setNames(data.frame(t(x$values)), x$names)))
    
    #     a     b     c     x
    #   <dbl> <dbl> <dbl> <dbl>
    #1    25    13    11    NA
    #2    12    10    NA     2
    
    rbind_列表(lappy(列表1,函数(x)集合名(data.frame(t(x$value)),x$names)))
    #a b c x
    #      
    #1251311 NA
    #2 12 10 NA 2
    
    仅使用基本R

    body <- do.call('rbind', lapply(list1, function(list.element){
      element.vals <- list.element[['values']]
      element.names <- list.element[['names']]
      names(element.vals) <- element.names
      return.vals <- element.vals[names]
      if(all(is.na(return.vals))) NULL else return.vals
    }))
    
    df <- as.data.frame(body)
    names(df) <- names
    df
    
    底部R中的主体

    t(sapply(list1, function(x) setNames(x$values, names)[match(names, x$names)]))
    #       a  b  c
    # [1,] 25 13 11
    # [2,] 12 10 NA
    

    为了完整起见,下面是一种使用
    dcast()
    rowid()
    的方法:


    A
    data.table
    解决方案:
    库(data.table);rbindlist(lappy(list1,函数(x)setNames(transpose(x)[2,],x$names)),use.names=TRUE,fill=TRUE)[,.SD,.SDcols=(a:c)]
    。非常感谢,这非常有效——还有解决因子值的方法吗?(如果值是一个因子)?对于因子也可以这样做吗?(例如,如果值是因子还是字符串?)我意识到它是有效的,但只有当数值和因子值不混合时才有效!非常感谢,阿克伦!!!太棒了@托比亚希,谢谢。这有点奇怪。您可以尝试在%!!名称中使用
    过滤器(如.character(names)%
    t(sapply(list1, function(x) setNames(x$values, names)[match(names, x$names)]))
    #       a  b  c
    # [1,] 25 13 11
    # [2,] 12 10 NA
    
    library(data.table)
    nam <- names1   # avoid name conflict with column name
    rbindlist(list1)[names1 %in% nam, dcast(.SD, rowid(names1) ~ names1)][, names1 := NULL][]
    
          a  b    c
    1: val1 13   11
    2:   12 10 <NA>
    
    library(data.table)
    rbindlist(list1)[, dcast(.SD, rowid(names1) ~ names1)][, .SD, .SDcols = names1]