Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:合并列和具有相同列名的值_R_Merge - Fatal编程技术网

R:合并列和具有相同列名的值

R:合并列和具有相同列名的值,r,merge,R,Merge,我有一个超过100列的电子表格,许多列都有相同的名称。我想合并那些具有相同名称的列,并对这些列中的值进行行和。我认为条件执行if()应该这样做,但我一直在为相同的列名编写条件?合并和求和列的函数是什么?合并()?还是行和() aa一种方法 sapply(unique(names(df)), function(i)rowSums(df[names(df) == i])) # B C U #[1,] 2 2 1 #[2,] 4 4 2 #[3,] 6 6 3 #[4,] 8 8 4 一种

我有一个超过100列的电子表格,许多列都有相同的名称。我想合并那些具有相同名称的列,并对这些列中的值进行行和。我认为条件执行if()应该这样做,但我一直在为相同的列名编写条件?合并和求和列的函数是什么?合并()?还是行和()

aa一种方法

sapply(unique(names(df)), function(i)rowSums(df[names(df) == i]))

#     B C U
#[1,] 2 2 1
#[2,] 4 4 2
#[3,] 6 6 3
#[4,] 8 8 4
一种方法是

sapply(unique(names(df)), function(i)rowSums(df[names(df) == i]))

#     B C U
#[1,] 2 2 1
#[2,] 4 4 2
#[3,] 6 6 3
#[4,] 8 8 4
解决方案1 使用
split()


解决方案2 将
rowSums()
调用替换为
Reduce()
/
`+`()


解决方案3 使用直接拆分data.frame(作为未分类列表)替换索引向量中间人:

do.call(cbind,lapply(split(as.list(df),names(df)),function(x) Reduce(`+`,x)));
##      B C U
## [1,] 2 2 1
## [2,] 4 4 2
## [3,] 6 6 3
## [4,] 8 8 4

标杆管理
库(microbenchmark);
bgoldst1解决方案1
使用
split()


解决方案2 将
rowSums()
调用替换为
Reduce()
/
`+`()


解决方案3 使用直接拆分data.frame(作为未分类列表)替换索引向量中间人:

do.call(cbind,lapply(split(as.list(df),names(df)),function(x) Reduce(`+`,x)));
##      B C U
## [1,] 2 2 1
## [2,] 4 4 2
## [3,] 6 6 3
## [4,] 8 8 4

标杆管理
库(microbenchmark);

bgoldst1这里是另一个选项,使用
data.table
中的
melt/dcast
。我们将'data.frame'转换为'data.table'(
setDT(df1)
),创建一个行号列('rn'),
melt
从'wide'格式转换为'long'格式,然后通过将
fun.aggregate
指定为
sum
将其转换为'wide'

library(data.table)
setDT(df1)[, rn :=  1:.N]
dcast(melt(df1, id.var= "rn"), rn ~variable, value.var="value", sum)[, rn:= NULL][]
#   B C U
#1: 2 2 1
#2: 4 4 2
#3: 6 6 3
#4: 8 8 4

下面是另一个选项,该选项使用
data.table
中的
melt/dcast
。我们将'data.frame'转换为'data.table'(
setDT(df1)
),创建一个行号列('rn'),
melt
从'wide'格式转换为'long'格式,然后通过将
fun.aggregate
指定为
sum
将其转换为'wide'

library(data.table)
setDT(df1)[, rn :=  1:.N]
dcast(melt(df1, id.var= "rn"), rn ~variable, value.var="value", sum)[, rn:= NULL][]
#   B C U
#1: 2 2 1
#2: 4 4 2
#3: 6 6 3
#4: 8 8 4

一点问题也没有:)谢谢你,博格斯特!解决方案1和2出现了此错误:df[x]中的错误:“closure”类型的对象不可子集。但解决方案3奏效了。对我来说已经够好了@SoonHweeN谢谢!您收到的错误消息一定是由于未将
df
分配给任何值造成的。在搜索路径中的
stats
包中有一个内置函数
df()
,因此如果您自己没有分配
df
,那么代码中对
df
的任何引用都将绑定到该函数。如果已将
df
分配给输入data.frame,则所有3种解决方案都应有效。完全没有问题:)谢谢,bgoldst!解决方案1和2出现了此错误:df[x]中的错误:“closure”类型的对象不可子集。但解决方案3奏效了。对我来说已经够好了@SoonHweeN谢谢!您收到的错误消息一定是由于未将
df
分配给任何值造成的。在搜索路径中的
stats
包中有一个内置函数
df()
,因此如果您自己没有分配
df
,那么代码中对
df
的任何引用都将绑定到该函数。如果已将
df
分配给输入data.frame,则所有3种解决方案都应有效。
library(microbenchmark);

bgoldst1 <- function(df) do.call(cbind,lapply(split(seq_len(ncol(df)),names(df)),function(x) rowSums(df[x])));
bgoldst2 <- function(df) do.call(cbind,lapply(split(seq_len(ncol(df)),names(df)),function(x) Reduce(`+`,df[x])));
bgoldst3 <- function(df) do.call(cbind,lapply(split(as.list(df),names(df)),function(x) Reduce(`+`,x)));
sotos <- function(df) sapply(unique(names(df)), function(i)rowSums(df[names(df) == i]));
df <- data.frame(B=c(1L,2L,3L,4L),C=c(1L,2L,3L,4L),U=c(1L,2L,3L,4L),B=c(1L,2L,3L,4L),C=c(1L,2L,3L,4L),check.names=F);

ex <- bgoldst1(df);
all.equal(ex,sotos(df)[,colnames(ex)]);
## [1] TRUE
all.equal(ex,bgoldst2(df));
## [1] TRUE
all.equal(ex,bgoldst3(df));
## [1] TRUE

microbenchmark(bgoldst1(df),bgoldst2(df),bgoldst3(df),sotos(df));
## Unit: microseconds
##          expr     min       lq     mean   median      uq      max neval
##  bgoldst1(df) 245.473 258.3030 278.9499 272.4155 286.742  641.052   100
##  bgoldst2(df) 156.949 166.3580 184.2206 171.7030 181.539 1042.618   100
##  bgoldst3(df)  82.110  92.5875 100.9138  97.2915 107.128  170.207   100
##     sotos(df) 200.997 211.9030 226.7977 223.6630 235.210  328.010   100
set.seed(1L);
NR <- 1e3L; NC <- 1e3L;
df <- setNames(nm=LETTERS[sample(seq_along(LETTERS),NC,T)],data.frame(replicate(NC,sample(seq_len(NR*3L),NR,T))));

ex <- bgoldst1(df);
all.equal(ex,sotos(df)[,colnames(ex)]);
## [1] TRUE
all.equal(ex,bgoldst2(df));
## [1] TRUE
all.equal(ex,bgoldst3(df));
## [1] TRUE

microbenchmark(bgoldst1(df),bgoldst2(df),bgoldst3(df),sotos(df));
## Unit: milliseconds
##          expr       min        lq      mean    median        uq      max neval
##  bgoldst1(df) 11.070218 11.586182 12.745706 12.870209 13.234997 16.15929   100
##  bgoldst2(df)  4.534402  4.680446  6.161428  6.097900  6.425697 44.83254   100
##  bgoldst3(df)  3.430203  3.555505  5.355128  4.919931  5.219930 41.79279   100
##     sotos(df) 19.953848 21.419628 22.713282 21.829533 22.280279 60.86525   100
library(data.table)
setDT(df1)[, rn :=  1:.N]
dcast(melt(df1, id.var= "rn"), rn ~variable, value.var="value", sum)[, rn:= NULL][]
#   B C U
#1: 2 2 1
#2: 4 4 2
#3: 6 6 3
#4: 8 8 4