加速R语言循环以将多个变量粘贴在一起

3

我是新手,需要一些帮助。我有一个数据框列表,对于列表内的每个元素(即data.frame),我希望快速地将一个数据集中的一列复制到同一数据集中的多个其他列中,仅用句号(“.”)分隔。

因此,如果我有一个数据集在一个数据框列表中:

list1[[1]]

A  B  C
2  1  5
4  2  2

然后我希望得到以下结果:
list1[[1]]

 A    B   C
2.5  1.5  5
4.2  2.2  2  

当 C 分别粘贴到 A 和 B 中时,我希望对列表中的每个数据框执行此操作。

我尝试了以下方法:

pasteX<-function(df) {for (i in 1:dim(df)[2]-1) {
df[,i]<-as.numeric(sprintf("%s.%s", df[,i], df$C))
}
return(df)}
list2<-lapply(list1, pasteX)

但是对于较大的矩阵和列表,这种方法非常缓慢。有没有推荐的方法可以使这段代码更快?谢谢!

1
欢迎。最好以更易读的方式提供您的数据:https://dev59.com/eG025IYBdhLWcg3whGSx - tjebo
2
啊,谢谢你分享这个……从现在开始我会更注意如何呈现我的数据和问题! - zeekster26
3个回答

4
假设所有内容都是小于10的整数。
lapply(list1, function(x){
    x[,-3] <- x[,-3] + x[,3]/10
    x})

3
我们可以使用Map
list1[[1]][-3] <- Map(function(x, y) as.numeric(sprintf('%s.%s', x, y)), 
                     list1[[1]][-3], list1[[1]][3])

如果有很多数据集,可以使用lapply循环,将前两列转换为matrix并与第三列拼接,更新输出并返回数据集。
lapply(list1, function(x)  {
     x[1:2] <- as.numeric(sprintf('%s.%s', as.matrix(x[1:2]), x[,3]));
     x })
#[[1]]
#    A   B C
#1 2.5 1.5 5
#2 4.2 2.2 2

或者使用 tidyverse

library(tidyverse)
map(list1, ~ .x %>%
               mutate_at(1:2, funs(as.numeric(sprintf('%s.%s', ., C)))))

或者使用 data.table
library(data.table)
lapply(list1,  function(x) setDT(x)[, (1:2) := 
     lapply(.SD, function(x) as.numeric(sprintf('%s.%s', x, C))) ,
             .SDcols = 1:2][])

谢谢,@akrun!这很有用,我现在要尝试实施并看看它能给我带来多少提升。 - zeekster26
@zeekster26 没问题。如果您正在检查基准测试,我还更新了一个data.table方法。请也检查一下。 - akrun
1
太好了!非常感激……我一直在尝试使用data.table方法,但做法有些错误。 - zeekster26
1
地图解决方案是目前最快的! - zeekster26

0

试试这个:

df <- data.frame(a = c(1,2,3), b = c(3,2,1), c = c(2,1,1))


pastex <- function(x){
 m<-  sapply(df[,1:2], function(x) as.numeric(paste(x, df$c, sep = '.')))
 m <- as.data.frame(m)
 m <- cbind(m, df["c"])
 return(m)
}

mylist <- list(df1 = df, df2 = df)

lapply(mylist, pastex)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接