我正在阅读文档,data.table并且还注意到了一些关于SO的对话,这些对话rbindlist应该比我更好rbind.
我想知道为什么rbindlist比真正优秀的rbind场景更好?rbindlistrbind
在内存利用方面有什么优势吗?
我刚刚开始使用R并遇到一个奇怪的行为:当在空数据框中插入第一行时,原始列名称会丢失.
例:
a<-data.frame(one = numeric(0), two = numeric(0))
a
#[1] one two
#<0 rows> (or 0-length row.names)
names(a)
#[1] "one" "two"
a<-rbind(a, c(5,6))
a
# X5 X6
#1 5 6
names(a)
#[1] "X5" "X6"
Run Code Online (Sandbox Code Playgroud)
如您所见,列名1和2被X5和X6替换.
有人可以告诉我为什么会这样,并且有没有正确的方法来做到这一点而不会丢失列名?
霰弹枪解决方案是将名称保存在辅助矢量中,然后在完成数据帧处理后将其添加回来.
谢谢
语境:
我创建了一个函数,它收集一些数据并将它们作为新行添加到作为参数接收的数据帧中.我创建数据框,遍历我的数据源,将data.frame传递给每个函数调用以填充其结果.
这只是在这里回答另一个问题.当您使用rbind两个数据框时,它会按名称而不是索引匹配列,这可能会导致意外行为:
> df<-data.frame(x=1:2,y=3:4)
> df
x y
1 1 3
2 2 4
> rbind(df,df[,2:1])
x y
1 1 3
2 2 4
3 1 3
4 2 4
Run Code Online (Sandbox Code Playgroud)
当然,有一些解决方法.例如:
rbind(df,rename(df[,2:1],names(df)))
data.frame(rbind(as.matrix(df),as.matrix(df[,2:1])))
Run Code Online (Sandbox Code Playgroud)
在编辑:rename从plyr包中实际上并没有这样工作(虽然我认为我最初写这篇文章的时候有工作......).通过重命名来实现此目的的方法是使用SimonO101的解决方案:
rbind(df,setNames(df[,2:1],names(df)))
Run Code Online (Sandbox Code Playgroud)
也许,令人惊讶的是,
data.frame(rbindlist(list(df,df[,2:1])))
Run Code Online (Sandbox Code Playgroud)
通过索引工作(如果我们不介意数据表,那么它非常简洁),所以这是一个区别do.call(rbind).
问题是,rbind对于名称不匹配的两个数据框,最简洁的方法是什么?我知道这似乎微不足道,但这种事情最终会使代码混乱.而且我不想写一个叫做的新函数rbindByIndex.理想情况下它会是这样的rbind(df,df[,2:1],byIndex=T).
我有一组包含不同列的数据框.我想将它们按行组合成一个数据帧.我习惯plyr::rbind.fill这样做.我正在寻找能够更有效地完成这项工作的东西,但这与此处给出的答案类似
require(plyr)
set.seed(45)
sample.fun <- function() {
nam <- sample(LETTERS, sample(5:15))
val <- data.frame(matrix(sample(letters, length(nam)*10,replace=TRUE),nrow=10))
setNames(val, nam)
}
ll <- replicate(1e4, sample.fun())
rbind.fill(ll)
Run Code Online (Sandbox Code Playgroud) 我需要rbind两个大数据帧.现在我用
df <- rbind(df, df.extension)
Run Code Online (Sandbox Code Playgroud)
但我(几乎)立即失去记忆.我猜是因为df在内存中保存两次.我可能会在未来看到更大的数据帧,所以我需要某种就地rbind.
所以我的问题是:在使用rbind时,有没有办法避免内存中的数据重复?
我发现这个问题,使用SqlLite,但我真的想避免使用硬盘作为缓存.
绑定向量时,rbind不检查列名:
l = list(row1 = c(10, 20), row2 = c(20, 10))
names(l$row1) = c("A", "B")
names(l$row2) = c("B", "A")
l
$row1
A B
10 20
$row2
B A
20 10
rbind(l$row1, l$row2)
A B
[1,] 10 20
[2,] 20 10
Run Code Online (Sandbox Code Playgroud)
如何从多个列表元素生成此矩阵,确保列名在行间正确匹配:
A B
[1,] 10 20
[2,] 10 20
Run Code Online (Sandbox Code Playgroud) 目标是将有时包含缺失记录的嵌套列表转换为数据框.缺少记录时的结构示例如下:
str(mylist)
List of 3
$ :List of 7
..$ Hit : chr "True"
..$ Project: chr "Blue"
..$ Year : chr "2011"
..$ Rating : chr "4"
..$ Launch : chr "26 Jan 2012"
..$ ID : chr "19"
..$ Dept : chr "1, 2, 4"
$ :List of 2
..$ Hit : chr "False"
..$ Error: chr "Record not found"
$ :List of 7
..$ Hit : chr "True"
..$ Project: chr "Green"
..$ Year : chr "2004" …Run Code Online (Sandbox Code Playgroud) 我的问题是如何在系统R中加入两个或多个数据帧?
例如:
我有两个数据框:
第一:
x y z
1 3 2 4
2 4 5 7
3 5 6 8
Run Code Online (Sandbox Code Playgroud)
第二:
x y z
1 1 1 1
2 4 5 7
Run Code Online (Sandbox Code Playgroud)
我需要这个:
x y z
1 3 2 4
2 4 5 7
3 5 6 8
4 1 1 1
5 4 5 7
Run Code Online (Sandbox Code Playgroud)
我试图为每个向量使用append,如下所示:
for(i in 1:length(first)){
Run Code Online (Sandbox Code Playgroud)mix[[i]]<-append(first[i], second[i])}f <-do.call(rbind,mix)
但它不像我需要的那样工作.我没有得到我的矩阵,我有一些不同的结构.
我试图将嵌套列表结构转换为数据帧.该列表看起来类似于以下内容(它是使用httr包读取的解析JSON中的序列化数据).
myList <- list(object1 = list(w=1, x=list(y=0.1, z="cat")), object2 = list(w=NULL, x=list(z="dog")))
Run Code Online (Sandbox Code Playgroud)
编辑:我原来的示例数据太简单了.实际数据是不规则的,这意味着并非每个对象都存在所有变量,并且一些列表元素为NULL.我编辑了数据以反映这一点.
unlist(myList)在递归展平列表方面做得非常好,然后我可以用它lapply来很好地展平所有对象.
flatList <- lapply(myList, FUN= function(object) {return(as.data.frame(rbind(unlist(object))))})
Run Code Online (Sandbox Code Playgroud)
最后,我可以使用它来关闭它 plyr::rbind.fill
myDF <- do.call(plyr::rbind.fill, flatList)
str(myDF)
#'data.frame': 2 obs. of 3 variables:
#$ w : Factor w/ 2 levels "1","2": 1 2
#$ x.y: Factor w/ 2 levels "0.1","0.2": 1 2
#$ x.z: Factor w/ 2 levels "cat","dog": 1 2
Run Code Online (Sandbox Code Playgroud)
问题是w和xy现在被解释为字符向量,默认情况下会将其解析为数据帧中的因子.我认为这unlist()是罪魁祸首,但我无法想出另一种递归展平列表结构的方法.解决方法是对数据帧进行后处理,然后分配数据类型.确定向量是有效数值向量还是整数向量的最佳方法是什么?
的调度机制R的功能rbind()和cbind()是非标准.当其中一个论点是a时,我探索了写作rbind.myclass()或cbind.myclass()函数的一些可能性data.frame,但到目前为止我还没有一个令人满意的方法.这篇文章集中于rbind,但同样适用cbind.
让我们创建一个rbind.myclass()函数,只需在调用时回显.
rbind.myclass <- function(...) "hello from rbind.myclass"
Run Code Online (Sandbox Code Playgroud)
我们创建了一个类的对象,myclass以下调用rbind所有正确的调度rbind.myclass()
a <- "abc"
class(a) <- "myclass"
rbind(a, a)
rbind(a, "d")
rbind(a, 1)
rbind(a, list())
rbind(a, matrix())
Run Code Online (Sandbox Code Playgroud)
但是,当其中一个参数(这不一定是第一个)时,rbind()将调用base::rbind.data.frame():
rbind(a, data.frame())
Run Code Online (Sandbox Code Playgroud)
这种行为有点令人惊讶,但它实际上已在文档中
dispatch记录rbind().给出的建议是:
如果要将其他对象与数据帧组合在一起,可能需要先将它们强制转换为数据帧.
实际上,这个建议可能难以实施.转换为数据框可能会删除基本类信息.此外,在发出命令之后,可能不知道该建议的用户可能会遇到错误或意外结果rbind(a, x).
第一种可能性是警告用户在数据帧rbind(a, x)时不应该进行呼叫x.相反,包的用户mypackage应该显式调用隐藏函数:
mypackage:::rbind.myclass(a, x)
Run Code Online (Sandbox Code Playgroud)
这可以完成,但用户必须记住在需要时进行显式调用.调用隐藏函数是最后的手段,不应该是常规策略. …