枢转,使用R CSV文件(Pivoting a CSV file using R)

2019-09-21 01:27发布

我有一个看起来像这样的文件:

                 type          created_at repository_name
1         IssuesEvent 2012-03-11 06:48:31       bootstrap
2         IssuesEvent 2012-03-11 06:48:31       bootstrap
3         IssuesEvent 2012-03-11 06:48:31       bootstrap
4         IssuesEvent 2012-03-11 06:52:50       bootstrap
5         IssuesEvent 2012-03-11 06:52:50       bootstrap
6         IssuesEvent 2012-03-11 06:52:50       bootstrap
7   IssueCommentEvent 2012-03-11 07:03:57       bootstrap
8   IssueCommentEvent 2012-03-11 07:03:57       bootstrap
9   IssueCommentEvent 2012-03-11 07:03:57       bootstrap
10        IssuesEvent 2012-03-11 07:03:58       bootstrap
11        IssuesEvent 2012-03-11 07:03:58       bootstrap
12        IssuesEvent 2012-03-11 07:03:58       bootstrap
13         WatchEvent 2012-03-11 07:15:44       bootstrap
14         WatchEvent 2012-03-11 07:15:44       bootstrap
15         WatchEvent 2012-03-11 07:15:44       bootstrap
16         WatchEvent 2012-03-11 07:18:45        hogan.js
17         WatchEvent 2012-03-11 07:18:45        hogan.js
18         WatchEvent 2012-03-11 07:18:45        hogan.js

说我有可以访问工作数据集https://github.com/aronlindberg/VOSS-Sequencing-Toolkit/blob/master/twitter_exploratory_analysis/twitter_events_mini.csv 。

我想创建一个具有在“repository_name”列中的每个条目列的表(例如引导,hogan.js)。 在此专栏中,我需要从对应于该项目(即仅行形成了目前的“类型”一栏也已在当前“repository_name”列“引导”的值应该落在下的“类型”列有数据新的“引导”栏)。 因此:

  • 时间戳仅仅是订货和不需要通过在该行同步(事实上它们可以被删除,因为该数据是根据时间戳已经排序)
  • 即使“IssuesEvent”重复10X我需要保留所有的这些,因为我将使用R包占美娜做序列分析
  • 列可以是不相等的长度的
  • 有不同的回购列之间没有关系(“repository_name”)

换句话说,我想一个表,看起来是这样的:

     bootstrap            hogan.js
1    IssuesEvent          PushEvent
2    IssuesEvent          IssuesEvent
3    OssueCommentEvent    WatchEvent

我怎样才能R中做到这一点?

一些使用重塑包我的失败尝试上可以找到https://github.com/aronlindberg/VOSS-Sequencing-Toolkit/blob/master/twitter_exploratory_analysis/reshaping_bigqueries.R 。

Answer 1:

您的样本数据:

data <- structure(list(type = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("IssueCommentEvent", 
"IssuesEvent", "WatchEvent"), class = "factor"), created_at = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 
6L), .Label = c("2012-03-11 06:48:31", "2012-03-11 06:52:50", 
"2012-03-11 07:03:57", "2012-03-11 07:03:58", "2012-03-11 07:15:44", 
"2012-03-11 07:18:45"), class = "factor"), repository_name = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L), .Label = c("bootstrap", "hogan.js"), class = "factor")), .Names = c("type", 
"created_at", "repository_name"), class = "data.frame", row.names = c(NA, 
-18L))

我从你只想要一个你的预期输出收集type时,它同样多次表明了created_at值,换句话说,你想删除重复:

data <- unique(data)

然后,提取所有type每个条目repository_name在它们出现的顺序,你可以简单地使用:

data.split <- split(data$type, data$repository_name)
data.split
# $bootstrap
# [1] IssuesEvent       IssuesEvent       IssueCommentEvent
# [4] IssuesEvent       WatchEvent       
# Levels: IssueCommentEvent IssuesEvent WatchEvent
# 
# $hogan.js
# [1] WatchEvent
# Levels: IssueCommentEvent IssuesEvent WatchEvent

它返回一个列表,它是所选择的R数据结构,用于具有不同长度的向量的集合。

编辑:既然你已经提供的输出数据的一个例子,它已经变得更加明显,你的预期输出确实是一个data.frame。 您可以将上面的列表中与填充一个data.frame NA S使用以下功能:

list.to.df <- function(arg.list) {
   max.len  <- max(sapply(arg.list, length))
   arg.list <- lapply(arg.list, `length<-`, max.len)
   as.data.frame(arg.list)
}

df.out <- list.to.df(data.split)
df.out
#           bootstrap   hogan.js
# 1       IssuesEvent WatchEvent
# 2       IssuesEvent       <NA>
# 3 IssueCommentEvent       <NA>
# 4       IssuesEvent       <NA>
# 5        WatchEvent       <NA>

然后,您可以使用保存到一个文件

write.csv(df.out, file = "out.csv", quote = FALSE, na = "", row.names = FALSE)

得到完全相同的输出格式为你在GitHub上发布的一个。



Answer 2:

我刚刚加入计算器; 希望我的回答是有点用的。

由表中,我假定你的意思是你想要的数据帧。 然而,似乎不太可能列是等长的,它看起来像行不会有多大的意义呢。 也许一个列表会更好?

下面是一个混乱的解决方案:

names <- unique(olddataframe$repository_name)
results <- sapply(1:length(names), function(j){
    sapply(which(olddataframe$repository_name == names[j]), function(i){
        olddataframe$type[i]
   )
})
names(results) <- names
results


Answer 3:

使用@ flodel的data对象,你也可以尝试aggregate()但有许多事件类型,这将很快成为不可读:

aggregate(list(Type = unique(data)$type), 
          list(Repository = unique(data)$repository_name), 
          function(x) paste0(x))
#   Repository                                                                 Type
# 1  bootstrap IssuesEvent, IssuesEvent, IssueCommentEvent, IssuesEvent, WatchEvent
# 2   hogan.js                                                           WatchEvent

你也可以尝试reshape()并做一些权谋与t()转),如下图所示。

temp = unique(data)
temp = reshape(temp, direction = "wide", 
               idvar="repository_name", timevar="created_at")
# If you want to keep the times, remove `row.names=NULL` below
temp1 = data.frame(t(temp[-1]), row.names=NULL)
names(temp1) = t(temp[1])
temp1
#           bootstrap   hogan.js
# 1       IssuesEvent       <NA>
# 2       IssuesEvent       <NA>
# 3 IssueCommentEvent       <NA>
# 4       IssuesEvent       <NA>
# 5        WatchEvent       <NA>
# 6              <NA> WatchEvent

但是,我发现,所有这些的NAS是令人厌恶的; 我要说的是,@ flodel的回答是最直接的,可能从长远来看,最有用的(也就是,不知道正是你想做的事,一旦你以这种形式获得的数据是什么 )。

更新(更多挂羊头卖狗肉)

(其实,这是一个“所以非​​常适合拖沓”的时刻)

我最后的(非常低效的)答案如下。

按上述步骤操作,但下降的日期/时间的东西,并从要素转换为字符。

# Using @flodel's data
temp1 = unique(data)[-2]
# Remove the factors
temp1[sapply(temp1, is.factor)] = lapply(temp1[sapply(temp1, is.factor)], 
                                         as.character)
# Split and unlist your data
temp2 = split(temp1[-c(2:3)], temp1$repository_name)
temp3 = sapply(temp2, as.vector)

rbind()cbind()将不同长度的“回收”对象,使它们的长度相同,但我们不希望出现这种情况。 所以,我们要力R相信,长度是相同的。 因此,找出最大长度。 虽然我们在这,在提取名称的清理版本temp3对象。

# What is the max number of rows we need?
LEN = max(sapply(temp3, length))
# What are the names we want for our columns?
NAMES = gsub(".type", "", names(temp3))

现在,提取的物品temp3到工作区,并确保它们都具有相同的长度。

# Use assign to unlist the vectors to the workspace
for (i in 1:length(temp3)) assign(NAMES[i], temp3[[i]])
# Make sure they have the same lengths
length(hogan.js) = LEN
length(bootstrap) = LEN

最后,使用cbind()来把你的数据一起。

# Use cbind to put these together
data.frame(cbind(bootstrap, hogan.js))
#           bootstrap   hogan.js
# 1       IssuesEvent WatchEvent
# 2       IssuesEvent       <NA>
# 3 IssueCommentEvent       <NA>
# 4       IssuesEvent       <NA>
# 5        WatchEvent       <NA>


文章来源: Pivoting a CSV file using R