R变长长度矢量或变量列表

时间:2015-06-01 19:02:03

标签: r list vector d3.js dataframe

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

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

这是一行。标题是:

Person, Email, Location, Communities, Workgroups

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

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

我所拥有的代码是从data.frame中读取,该数据是特定社区成员的列表,并将该社区的名称添加到所有员工的主数据框架中的列中。我通过电子邮件地址编制索引,因为它是唯一的。因此,这个特定的循环查看data.frame中的每个单独的电子邮件地址,称为" commTD"并在一个名为" testr。"的主数据框架中找到它。如果找到它,它会查看社区变量,并将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中是不可能的,在数据​​框中将长度不同的向量或列表作为单个变量?

1 个答案:

答案 0 :(得分:3)

根据定义,数据框是一个长度相等的向量列表,所以当你问这是否可以作为一个类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...

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

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)

希望它有所帮助。