【问题标题】:extracting one set of multiple variables in a list of data.frames in R在R中的data.frames列表中提取一组多个变量
【发布时间】:2019-06-21 14:47:27
【问题描述】:

假设我有一个data.frame,比如THIS。在名为autoreg 的列之后的任何数据列都是用户定义的任意列。所以,我不知道列名或值。例如,在 THIS data.frame 列中命名为:"ESL" "prof" "scope" "type" 由用户定义。

问题:

我怎样才能有一个循环结构(在 BASE R 中),在每一轮中提取一组任意列? 我想要的输出是一个列表,其中每个研究的 ESL 值 prof 值 scope 值和 type 值彼此相邻。

我尝试了两个嵌套的lapply(见下文),它们提取了这些任意列的所有集合的所有值,但是我如何一次提取这些任意列中的每一个?

D <- read.csv("https://raw.githubusercontent.com/izeh/i/master/i.csv", h = T) ## data.frame
L <- split(D, D$study.name) ; L[[1]] <- NULL

arb.names <- c("ESL", "prof", "scope", "type") ## arbitrary column names 

a <- lapply(1:length(arb.names), function(j) lapply(1:length(L), function(i) L[[i]][arb.names[j]]))

【问题讨论】:

    标签: r function loops dataframe lapply


    【解决方案1】:

    可能我们需要grep 'arb.names' 来从 'L' 中提取列集

    lapply(arb.names, function(nm) lapply(L, function(l1) l1[grep(nm, names(l1))]))
    

    如果我们想将list 中的不同名称组合为一个list,请使用transpose

    library(purrr)
    lapply(arb.names, function(nm) transpose(lapply(L, function(l1) l1[grep(nm, names(l1))])))
    

    或使用base R

    m1 <- simplify2array(lapply(arb.names, function(nm)
          lapply(L, function(l1) l1[grep(nm, names(l1))])))
    split(m1, col(m1))
    

    【讨论】:

    • @rnorouzian 但是,他们是否有相同的行数来创建一个data.frame
    • @rnorouzian 那么你可以使用lapply(arb.names, function(nm) transpose(lapply(L, function(l1) l1[grep(nm, names(l1))])))
    • @rnorouzian 你可以在第二个代码中使用相同的格式(只是为了确保你想要在 base R 中)
    • @rnorouzian 更新了帖子
    • 你的卓越永远会脱颖而出,你真的超越了这些。无论如何,我会等待你的答复,我非常感激。
    【解决方案2】:

    虽然这个问题有一个公认的答案,但我想提出一种完全不同的方法。

    如果我理解正确,OP 正在寻找一种方法来轻松比较不同研究之间任意列中的值。作为额外的复杂性,任意列的名称事先是未知的。

    我的建议是适当地重塑数据:

    library(data.table)
    library(magrittr)
    melt(setDT(D), id.vars = c("study.name", "group.name"), 
         measure.vars = tail(names(D), -grep("autoreg", names(D))), na.rm = TRUE) %>%
      dcast(variable + study.name ~ group.name)
    
        variable study.name Cont.Long Cont.Long2 Cont.Short DCF.Long DCF.Long2 DCF.Short ME.long ME.long2 ME.short
     1:      ESL  Ellis.sh1         1         NA          1        1        NA         1       1       NA        1
     2:      ESL      Goey1         0         NA          0        0        NA         0       0       NA        0
     3:      ESL      kabla         1          1          1        1         1         1       1        1        1
     4:     prof  Ellis.sh1         2         NA          2        2        NA         2       2       NA        2
     5:     prof      Goey1         1         NA          1        1        NA         1       1       NA        1
     6:     prof      kabla         3          3          3        3         3         3       3        3        3
     7:    scope  Ellis.sh1         0         NA          0        0        NA         0       0       NA        0
     8:    scope      Goey1         1         NA          1        1        NA         1       1       NA        1
     9:    scope      kabla         0          0          0        0         0         0       0        0        0
    10:     type  Ellis.sh1         1         NA          1        1        NA         1       1       NA        1
    11:     type      Goey1         0         NA          0        0        NA         0       0       NA        0
    12:     type      kabla         1          1          1        1         1         1       1        1        1
    

    作为任意列(重塑格式的列variable),所有列都是从D 中选取的,它们出现在列autoreg 之后,无论它们的名称如何

    tail(names(D), -grep("autoreg", names(D)))
    

    附录

    请注意,列名取自group.name,并按字母顺序排列。如果需要保持group.name 确实出现在D 中的原始行顺序,则需要相应调整group.name 的因子水平:

    library(data.table)
    library(magrittr)
    lvls <- D[study.name != "", 1:2] %>% 
      split(drop = TRUE, by = "study.name") %>% 
      .[lengths(.) %>% order() %>% rev()] %>% # merge longest first
      Reduce(function(x, y) merge(x, y, by = "group.name", all = TRUE, sort = FALSE), .) %>% 
      .[, group.name %>% forcats::fct_drop() %>% forcats::fct_inorder()] 
    melt(setDT(D), id.vars = c("study.name", "group.name"), 
         measure.vars = tail(names(D), -grep("autoreg", names(D))), na.rm = TRUE) %>%
      .[, group.name := factor(group.name, levels = lvls)] %>% 
      dcast(variable + study.name ~ group.name)
    
        variable study.name ME.short ME.long ME.long2 DCF.Short DCF.Long DCF.Long2 Cont.Short Cont.Long Cont.Long2
     1:      ESL  Ellis.sh1        1       1       NA         1        1        NA          1         1         NA
     2:      ESL      Goey1        0       0       NA         0        0        NA          0         0         NA
     3:      ESL      kabla        1       1        1         1        1         1          1         1          1
     4:     prof  Ellis.sh1        2       2       NA         2        2        NA          2         2         NA
     5:     prof      Goey1        1       1       NA         1        1        NA          1         1         NA
     6:     prof      kabla        3       3        3         3        3         3          3         3          3
     7:    scope  Ellis.sh1        0       0       NA         0        0        NA          0         0         NA
     8:    scope      Goey1        1       1       NA         1        1        NA          1         1         NA
     9:    scope      kabla        0       0        0         0        0         0          0         0          0
    10:     type  Ellis.sh1        1       1       NA         1        1        NA          1         1         NA
    11:     type      Goey1        0       0       NA         0        0        NA          0         0         NA
    12:     type      kabla        1       1        1         1        1         1          1         1          1
    

    数据

    由于将来外部链接可能会中断,这里是来自 github 链接的 OP 数据集:

    D <-
    structure(list(study.name = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 
    1L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
    4L), .Label = c("", "Ellis.sh1", "Goey1", "kabla"), class = "factor"), 
        group.name = structure(c(10L, 8L, 7L, 5L, 4L, 2L, 1L, 10L, 
        8L, 7L, 5L, 4L, 2L, 1L, 10L, 8L, 9L, 7L, 5L, 6L, 4L, 2L, 
        3L), .Label = c("", "Cont.Long", "Cont.Long2", "Cont.Short", 
        "DCF.Long", "DCF.Long2", "DCF.Short", "ME.long", "ME.long2", 
        "ME.short"), class = "factor"), n = c(13L, 13L, 15L, 15L, 
        16L, 16L, NA, 13L, 13L, 15L, 15L, 16L, 16L, NA, 13L, 13L, 
        13L, 15L, 15L, 15L, 16L, 16L, 16L), mpre = c(0.34, 0.34, 
        0.37, 0.37, 0.32, 0.32, NA, 0.34, 0.34, 0.37, 0.37, 0.32, 
        0.32, NA, 0.34, 0.34, 0.34, 0.37, 0.37, 0.37, 0.32, 0.32, 
        0.32), mpos = c(0.72, 0.39, 0.54, 0.49, 0.28, 0.35, NA, 0.72, 
        0.39, 0.54, 0.49, 0.28, 0.35, NA, 0.72, 0.39, 0.39, 0.54, 
        0.49, 0.49, 0.28, 0.35, 0.35), sdpre = c(0.37, 0.37, 0.38, 
        0.38, 0.37, 0.37, NA, 0.37, 0.37, 0.38, 0.38, 0.37, 0.37, 
        NA, 0.37, 0.37, 0.37, 0.38, 0.38, 0.38, 0.37, 0.37, 0.37), 
        sdpos = c(0.34, 0.36, 0.36, 0.36, 0.36, 0.32, NA, 0.34, 0.36, 
        0.36, 0.36, 0.36, 0.32, NA, 0.34, 0.36, 0.36, 0.36, 0.36, 
        0.36, 0.36, 0.32, 0.32), control = c(FALSE, FALSE, FALSE, 
        FALSE, TRUE, TRUE, NA, FALSE, FALSE, FALSE, FALSE, TRUE, 
        TRUE, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
        TRUE, TRUE), post = c(1L, 2L, 1L, 2L, 1L, 2L, NA, 1L, 2L, 
        1L, 2L, 1L, 2L, NA, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), 
        r = c(0.5, 0.5, 0.5, 0.5, 0.5, 0.5, NA, 0.5, 0.5, 0.5, 0.5, 
        0.5, 0.5, NA, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5
        ), autoreg = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
        NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, FALSE, 
        FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE), 
        ESL = c(1L, 1L, 1L, 1L, 1L, 1L, NA, 0L, 0L, 0L, 0L, 0L, 0L, 
        NA, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), prof = c(2L, 2L, 
        2L, 2L, 2L, 2L, NA, 1L, 1L, 1L, 1L, 1L, 1L, NA, 3L, 3L, 3L, 
        3L, 3L, 3L, 3L, 3L, 3L), scope = c(0L, 0L, 0L, 0L, 0L, 0L, 
        NA, 1L, 1L, 1L, 1L, 1L, 1L, NA, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
        0L, 0L), type = c(1L, 1L, 1L, 1L, 1L, 1L, NA, 0L, 0L, 0L, 
        0L, 0L, 0L, NA, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
    -23L))
    
        study.name group.name  n mpre mpos sdpre sdpos control post   r autoreg ESL prof scope type
     1:  Ellis.sh1   ME.short 13 0.34 0.72  0.37  0.34   FALSE    1 0.5   FALSE   1    2     0    1
     2:  Ellis.sh1    ME.long 13 0.34 0.39  0.37  0.36   FALSE    2 0.5   FALSE   1    2     0    1
     3:  Ellis.sh1  DCF.Short 15 0.37 0.54  0.38  0.36   FALSE    1 0.5   FALSE   1    2     0    1
     4:  Ellis.sh1   DCF.Long 15 0.37 0.49  0.38  0.36   FALSE    2 0.5   FALSE   1    2     0    1
     5:  Ellis.sh1 Cont.Short 16 0.32 0.28  0.37  0.36    TRUE    1 0.5   FALSE   1    2     0    1
     6:  Ellis.sh1  Cont.Long 16 0.32 0.35  0.37  0.32    TRUE    2 0.5   FALSE   1    2     0    1
     7:                       NA   NA   NA    NA    NA      NA   NA  NA      NA  NA   NA    NA   NA
     8:      Goey1   ME.short 13 0.34 0.72  0.37  0.34   FALSE    1 0.5   FALSE   0    1     1    0
     9:      Goey1    ME.long 13 0.34 0.39  0.37  0.36   FALSE    2 0.5   FALSE   0    1     1    0
    10:      Goey1  DCF.Short 15 0.37 0.54  0.38  0.36   FALSE    1 0.5   FALSE   0    1     1    0
    11:      Goey1   DCF.Long 15 0.37 0.49  0.38  0.36   FALSE    2 0.5   FALSE   0    1     1    0
    12:      Goey1 Cont.Short 16 0.32 0.28  0.37  0.36    TRUE    1 0.5   FALSE   0    1     1    0
    13:      Goey1  Cont.Long 16 0.32 0.35  0.37  0.32    TRUE    2 0.5   FALSE   0    1     1    0
    14:                       NA   NA   NA    NA    NA      NA   NA  NA      NA  NA   NA    NA   NA
    15:      kabla   ME.short 13 0.34 0.72  0.37  0.34   FALSE    1 0.5   FALSE   1    3     0    1
    16:      kabla    ME.long 13 0.34 0.39  0.37  0.36   FALSE    2 0.5   FALSE   1    3     0    1
    17:      kabla   ME.long2 13 0.34 0.39  0.37  0.36   FALSE    3 0.5   FALSE   1    3     0    1
    18:      kabla  DCF.Short 15 0.37 0.54  0.38  0.36   FALSE    1 0.5   FALSE   1    3     0    1
    19:      kabla   DCF.Long 15 0.37 0.49  0.38  0.36   FALSE    2 0.5   FALSE   1    3     0    1
    20:      kabla  DCF.Long2 15 0.37 0.49  0.38  0.36   FALSE    3 0.5   FALSE   1    3     0    1
    21:      kabla Cont.Short 16 0.32 0.28  0.37  0.36    TRUE    1 0.5   FALSE   1    3     0    1
    22:      kabla  Cont.Long 16 0.32 0.35  0.37  0.32    TRUE    2 0.5   FALSE   1    3     0    1
    23:      kabla Cont.Long2 16 0.32 0.35  0.37  0.32    TRUE    3 0.5   FALSE   1    3     0    1
        study.name group.name  n mpre mpos sdpre sdpos control post   r autoreg ESL prof scope type
    

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 2017-06-10
      • 2017-12-12
      • 2019-12-29
      • 1970-01-01
      • 2021-02-16
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多