【问题标题】:Generate column name using name of objects in list with apply in R使用列表中的对象名称生成列名,并在 R 中应用
【发布时间】:2016-08-21 18:05:24
【问题描述】:

希望这个问题也可以帮助其他 R 用户。

有一个包含多个对象(初始数据帧)的列表,所有对象都具有相同的结构。目标是融合每个对象并将第三个变量的名称替换为对应对象的名称,使用lapply

数据框是:

gdp <- data.frame(date = as.Date(c('2010-03-31','2010-06-30','2010-09-30','2010-12-31')),
       id1 = rnorm(4), id2 = rnorm(4), id3 = rnorm(4));
employ <- data.frame(date = as.Date(c('2010-03-31','2010-06-30','2010-09-30','2010-12-31')),
       id1 = rnorm(4), id2 = rnorm(4), id3 = rnorm(4));
fdi <- data.frame(date = as.Date(c('2010-03-31','2010-06-30','2010-09-30','2010-12-31')),
       id1 = rnorm(4), id2 = rnorm(4), id3 = rnorm(4));

包含数据框的列表是:

data.list <- list(gdp=gdp, employ=employ, fdi=fdi);

尝试将列表中的不同对象融合到面板数据结构中(使用id=c("date") 融合),并将第三个变量的名称(融合后名为value)替换为相应对象的名称(即gdpemployfdi),如下:

data.list <- lapply(data.list, function(x) {
    x <- melt(x, id = c("date"));
    setnames(x, c("date", "id", paste(names(data.list[x])))); x});

但是,这会导致以下错误消息:

"Error in data.list[x] : invalid subscript type 'list'"

感谢您分享您的知识!

【问题讨论】:

  • 它不是列表中的“x”对象吗? akrun 有解决方案吗?
  • 对不起,我没有检查{,因为没有缩进,我认为它是创建单独的对象。

标签: r list variables object lapply


【解决方案1】:

Map更适合这里,可以同时传递数据和名称,并设置对应的值名称,而使用lapply时,不能访问传递给函数以及元素的索引,因此不太适合:

Map(function(data, name) melt(data, id = "date", value.name = name), data.list, names(data.list))

# $gdp
#          date variable         gdp
# 1  2010-03-31      id1 -0.98490642
# 2  2010-06-30      id1 -0.65785037
# 3  2010-09-30      id1  1.84931510
# 4  2010-12-31      id1 -0.01380012
# 5  2010-03-31      id2 -1.07489986
# 6  2010-06-30      id2 -0.53073153
# 7  2010-09-30      id2 -0.41319361
# 8  2010-12-31      id2  0.07883559
# 9  2010-03-31      id3 -0.32027747
# 10 2010-06-30      id3  2.44528354
# 11 2010-09-30      id3  0.77611010
# 12 2010-12-31      id3 -0.20826479
# 
# $employ
#          date variable     employ
# 1  2010-03-31      id1 -0.8094097
# 2  2010-06-30      id1  0.1384562
# 3  2010-09-30      id1  0.5859650
# 4  2010-12-31      id1 -0.5393965
# 5  2010-03-31      id2 -1.0970997
# 6  2010-06-30      id2  1.0017547
# 7  2010-09-30      id2 -0.6750567
# 8  2010-12-31      id2 -0.2550456
# 9  2010-03-31      id3  0.8593821
# 10 2010-06-30      id3 -0.1797962
# 11 2010-09-30      id3 -0.9969474
# 12 2010-12-31      id3  1.9796193
# 
# $fdi
#          date variable          fdi
# 1  2010-03-31      id1 -0.003560763
# 2  2010-06-30      id1 -1.034493176
# 3  2010-09-30      id1 -0.382924576
# 4  2010-12-31      id1 -1.634971043
# 5  2010-03-31      id2  1.069739934
# 6  2010-06-30      id2 -0.953591914
# 7  2010-09-30      id2  0.980699511
# 8  2010-12-31      id2 -1.939297092
# 9  2010-03-31      id3  0.224597714
# 10 2010-06-30      id3 -0.199469601
# 11 2010-09-30      id3  0.710024455
# 12 2010-12-31      id3 -1.716196075

【讨论】:

  • 不错! purrr/tidyr 版本:data.list %&gt;% map2(names(.), ~gather_(.x, 'id', .y, paste0('id', 1:3)))
【解决方案2】:

我对这个问题的理解与 Psidom 有点不同: 可以直接使用melt就行了。通过使用reshape2::melt.list

melt(data.list, id=c("date"))

结果:

         date variable       value     L1
1  2010-03-31      id1  1.25281857    gdp
2  2010-06-30      id1 -0.48590454    gdp
3  2010-09-30      id1 -0.76352141    gdp
4  2010-12-31      id1 -0.74724889    gdp
5  2010-03-31      id2 -1.18055685    gdp
6  2010-06-30      id2 -0.28217948    gdp
7  2010-09-30      id2  0.69016828    gdp
8  2010-12-31      id2 -0.55827152    gdp
9  2010-03-31      id3  0.30202935    gdp
10 2010-06-30      id3  0.74974718    gdp
11 2010-09-30      id3 -0.57454843    gdp
12 2010-12-31      id3  0.24156810    gdp
13 2010-03-31      gdp  1.00000000    gdp
14 2010-06-30      gdp  1.00000000    gdp
15 2010-09-30      gdp  1.00000000    gdp
16 2010-12-31      gdp  1.00000000    gdp
17 2010-03-31      id1 -0.23128530 employ
18 2010-06-30      id1 -0.15230297 employ
19 2010-09-30      id1 -0.36702926 employ
20 2010-12-31      id1  0.73848140 employ
21 2010-03-31      id2  0.95324433 employ
22 2010-06-30      id2 -0.64710459 employ
23 2010-09-30      id2 -1.29508378 employ
24 2010-12-31      id2  1.40630293 employ
25 2010-03-31      id3 -2.25220973 employ
26 2010-06-30      id3  0.23300536 employ
27 2010-09-30      id3 -0.25745376 employ
28 2010-12-31      id3  0.81838150 employ
29 2010-03-31      id1  0.24334109    fdi
30 2010-06-30      id1 -1.06549136    fdi
31 2010-09-30      id1 -0.03566445    fdi
32 2010-12-31      id1  0.37610557    fdi
33 2010-03-31      id2 -1.11626811    fdi
34 2010-06-30      id2 -0.59906541    fdi
35 2010-09-30      id2 -0.34006607    fdi
36 2010-12-31      id2  1.02040731    fdi
37 2010-03-31      id3  0.65030238    fdi
38 2010-06-30      id3 -0.09420529    fdi
39 2010-09-30      id3 -0.34264768    fdi
40 2010-12-31      id3  0.89456456    fdi

【讨论】:

    【解决方案3】:

    我们可以将hadleyverse 语法与purrrtidyr 包一起使用

    library(purrr)
    library(tidyr)
    library(data.table)
    data.list %>% 
        map(~gather(., id, value, id1:id3)) %>% #convert to long format
        map2(names(data.list), ~setnames(.x, 'value', .y)) #change the column names
    # $gdp
    #         date      id        gdp
    #1  2010-03-31      id1 -0.7772369
    #2  2010-06-30      id1 -0.8056224
    #3  2010-09-30      id1  0.8542292
    #4  2010-12-31      id1 -1.1872451
    #5  2010-03-31      id2  0.8328595
    #6  2010-06-30      id2 -0.2474831
    #7  2010-09-30      id2 -0.9848888
    #8  2010-12-31      id2 -1.3365007
    #9  2010-03-31      id3 -0.8461187
    #10 2010-06-30      id3  0.3711446
    #11 2010-09-30      id3 -1.1862064
    #12 2010-12-31      id3  1.1424022
    
    #$employ
    #         date      id     employ
    #1  2010-03-31      id1  2.7989326
    #2  2010-06-30      id1 -1.2110057
    #3  2010-09-30      id1 -0.7821650
    #4  2010-12-31      id1 -0.3791048
    #5  2010-03-31      id2  0.1013004
    #6  2010-06-30      id2  1.3332404
    #7  2010-09-30      id2 -1.3893301
    #8  2010-12-31      id2 -0.8440842
    #9  2010-03-31      id3 -0.1077106
    #10 2010-06-30      id3 -0.7705078
    #11 2010-09-30      id3  1.4519592
    #12 2010-12-31      id3 -0.8737978
    
    #$fdi
    #         date      id         fdi
    #1  2010-03-31      id1  1.23107035
    #2  2010-06-30      id1 -0.26811221
    #3  2010-09-30      id1  0.33061470
    #4  2010-12-31      id1 -0.32557342
    #5  2010-03-31      id2 -0.30207594
    #6  2010-06-30      id2 -0.41945723
    #7  2010-09-30      id2 -0.20942161
    #8  2010-12-31      id2 -0.79545903
    #9  2010-03-31      id3 -0.01117631
    #10 2010-06-30      id3  0.99176069
    #11 2010-09-30      id3  0.22381746
    #12 2010-12-31      id3 -0.25679217
    

    注意:这也可以使用单个 map2 代码完成,但我认为通过两个步骤更容易理解该过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-21
      • 1970-01-01
      • 2013-02-19
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 2013-02-20
      • 1970-01-01
      相关资源
      最近更新 更多