【问题标题】:R varied length vector or list in variableR变长向量或变量列表
【发布时间】:2015-08-15 08:47:52
【问题描述】:

我正在使用 R 为 D3 可视化准备一些数据。可视化是使用以下结构创建的(这是 .csv 文件中的一行,随后在 javascript 中转换为 JSON)。

Joe.Schmoe, joe.schmoe@email.com, Sao Paulo, ["Community01", "Community02", "Community03"], 
["workgroup01","workgroup02"]

这是单行。标题将是:

Person, Email, Location, Communities, Workgroups

您会注意到“社区”和“工作组”列包含列表。此外,这些列表的长度会有所不同,具体取决于每个人所关联的社区和工作组。我认识到这可能不是关于数据“整洁”的最佳实践,但这是该可视化所期望的。

所以......在 R(我正在学习)中,我发现无法重新创建这个结构,因为当我尝试填充“社区”或“工作组”变量时,R 似乎期望每个变量将具有相同的长度。

我拥有的代码是从 data.frame 中读取的,它是特定社区成员的列表,并将该社区的名称添加到所有员工的主 data.frame 中的列中。我按电子邮件地址编制索引,因为它是唯一的。因此,这个特定的循环会查看名为“commTD”的 data.frame 中的每个单独的电子邮件地址,并在名为“testr”的主 data.frame 中找到它。如果找到它,它会查看 community 变量并将 NA 值替换为社区的名称(在本例中为“技术设计”),或者如果向量已经存在,则将 Technical Design 附加到它:

for(i in commTD$email){
    if(i %in% testr$email){
        tmpList <- testr[which(testr$email ==i) , 'communities']

        if(is.na(tmpList)){
            tmpList <- list(c("Technical Design"))
        }

        else{        
            tmpList <- append(tmpList[[1]][1], 'Technical Design')
        }

    testr[which(testr$email ==i) , 'communities'] <- list(tmpList)
    }   
} 

这适用于初始替换,但如果我将一个新社区附加到列表中,然后尝试将其传递回 testr data.frame,我会收到错误:

Error in `[<-.data.frame`(`*tmp*`, which(testr$email == i), "communities", 
: replacement has 2 rows, data has 1

您会注意到我正在尝试创建一个向量列表,这只是我尝试解决此问题的一种方法。我想也许我可以强制 R 将列表视为单个对象,即使它包含多个项目 - 或者在这种情况下是多个项目的向量。

这在 R 中是不可能的,将不同长度的向量或列表作为数据框中的单个变量?

【问题讨论】:

  • data.table 包支持list-class 列。我认为它不受支持的是基础 R。另外,听起来你在循环中所做的事情最好通过合并来完成。
  • 试试,例如DT &lt;- data.table(a=1:2,b=list(c(4,5),c(4,5,6))); DT下面是参考:stackoverflow.com/a/22536321/1191259
  • 谢谢,@Frank。 data.table 和 list -class 列在经过一番摸索后工作了。

标签: r list vector d3.js dataframe


【解决方案1】:

根据定义,数据帧是等长向量的列表,所以当你问这是否可能作为类 data.frame() 时,不,不是。

您可以按照建议使用另一种类型的对象,例如 data.table,或者另一种方式是将您想要的输出视为不相等向量的列表,以传递给您的 js。

那个对象看起来像这样:

dataList <- list(name = c("Joe.Schmoe", "Joe.Bloe"),
                 email = c("joe.schmoe@email.com", "joe.bloe@email.com"),
                 location = c("Sao Paulo", "London"),
                 Communities = list(c("Community01", "Community02", "Community03"), 
                                  c("Community02", "Community05", "Community03")
                 ),
                 Workgroups = list(c("workgroup01","workgroup02"), 
                                   c("workgroup01","workgroup03"))
                )

然后像数据框一样访问每个字段,以输出到您的 js:

dataList$name
dataList$Communities
etc...

根据 Frank 的建议,如果您想通过电子邮件地址访问每个条目,那么您可以像这样访问每个条目:

data_list[["joe.schmoe@email.com"]]

...然后以电子邮件的名称作为索引构建列表,如下所示:

data_list = list(`joe.schmoe@email.com`=list(name="Joe",
                                             location="Sao Paulo",
                                             Communities=....),
                 `joe.bloe@email.com`=list(n‌​ame="Joe", ...)) 

然后,您可以避免使用 for() 循环的非 R 风格,并开始享受 lapply() 系列函数的乐趣,以矢量化的方式处理所有条目。 (详见 ?lapply)

希望对你有帮助。

【讨论】:

  • 是的,虽然我认为将条目列表作为条目列表会更好,每个人一个......更容易构建。例如,data_list = list(`joe.schmoe@email.com`=list(name="Joe",...),`joe.bloe@email.com`=list(name="Joe")) OP 说数据是通过电子邮件“索引”的,所以这种安排似乎是明智的,并允许像 data_list[["joe.schmoe@email.com"]] 一样访问
猜你喜欢
  • 1970-01-01
  • 2013-08-23
  • 2013-01-25
  • 1970-01-01
  • 2021-02-12
  • 1970-01-01
  • 2011-04-04
  • 2016-05-08
  • 1970-01-01
相关资源
最近更新 更多