如何使用数据框内的列表快速扩展数据框

时间:2019-04-29 14:45:34

标签: r

我有一个数据框,其中包含一列具有唯一的字符串标识符,另一列具有简单的字符串/关键字,第三列是由逗号分隔的字符串(“类别”)。此数据框具有x行,并且第三列中的类别字符串可以具有任意数量的逗号。我想用逗号分割类别,将关键字字符串附加到每个分离的类别中,然后创建一个新数据框,该数据框由一个用于唯一字符串标识符的列和一个用于创建的每个新字符串的列组成。

这是我开始的DF的一个例子:

componentDidMount(){
  this.getNotes();
}

componentWillUnmount(){
  this.unsubscribe();
}

getNotes = () => {
  const db = this.props.firestore;
  const colRef = db.collection("users").doc(this.props.uid)
  .collection("notes");

  let notes = [];
  const that = this;

  // Realtime updates listener
  this.unsubscribe = colRef.orderBy("timestamp", "asc")
  .onSnapshot(function(querySnapshot) {
      var notes = [];
      querySnapshot.forEach(function(doc) {
          notes.push(
            { id: doc.id,
              body: doc.data().body}
              );
      });
      that.setState({ notes })
  });
}

这就是我想要的最终DF的样子:

startDF <- data.frame(uq_id = c("44ffd", "t3dd", "rrk33--ds", "limmt3"),
                      keyword = c("citizen", "river", "mouse", "hello"),
                      categories = c("App, Restaurant, Hotel", "Field, Place", "Movie", "App, Hotel, Theater, Show"))

目前,我正在遍历DF的每个元素,并逐行创建此新数据框,但这很慢,我觉得必须有一种更好的方法使用Apply,Strsplit,Paste等。 是否有一个快速简单的解决方案?谢谢!

2 个答案:

答案 0 :(得分:3)

使用tidyverseseparate_rows,我们可以先将每个category分成单独的行,然后在unite列中keyword

library(tidyverse)

startDF %>%
  separate_rows(categories) %>%
  unite(combo, keyword, categories, sep = " ")

#       uq_id              combo
#1      44ffd        citizen App
#2      44ffd citizen Restaurant
#3      44ffd      citizen Hotel
#4       t3dd        river Field
#5       t3dd        river Place
#6  rrk33--ds        mouse Movie
#7     limmt3          hello App
#8     limmt3        hello Hotel
#9     limmt3      hello Theater
#10    limmt3         hello Show

Base R方法可能是通过用逗号分割categories,基于每个uq_id的{​​{1}}重复length并通过将字符串粘贴在一起来创建新的数据帧与category一起使用keyword

mapply

使用list_cat <- strsplit(startDF$categories, ",") data.frame(uq_id = rep(startDF$uq_id, lengths(list_cat)), combo = unlist(mapply(paste, list_cat, startDF$keyword))) 读取startDF,以使它们作为字符而不是因子。

答案 1 :(得分:0)

另一种tidyverse可能性是:

startDF %>%
 mutate(categories = strsplit(as.character(categories), ", ", fixed = TRUE)) %>%
 unnest() %>%
 transmute(uq_id = uq_id,
           combo = paste(keyword, categories, sep = " "))

       uq_id              combo
1      44ffd        citizen App
2      44ffd citizen Restaurant
3      44ffd      citizen Hotel
4       t3dd        river Field
5       t3dd        river Place
6  rrk33--ds        mouse Movie
7     limmt3          hello App
8     limmt3        hello Hotel
9     limmt3      hello Theater
10    limmt3         hello Show