如何解决如何使用tidyverse应用功能列表并为每个应用功能获取一列
我试图将多个函数应用于数据集中的每一列,并为计算出的每个函数取回一列,然后这些行将对应于计算在哪一列上。因此,在下面的代码中,有3个ID。然后,我在每个函数上计算三个函数,因此最终数据帧将具有3行和3列。现在,这些行对应于在其上计算函数的ID,而列与所计算的值相对应。我对其他解决方案持开放态度,但希望使用tidyverse解决方案,因为我需要将其泛化为许多功能并保持快速。
预期输出在end.data
data <- data.frame(id1 = 1:10,id2 = 1:10,id3 = 1:10)
data
end.data <- data.frame(innprod = c(385,385,385),identity = c(55,55,55),range = c(9,9,9))
end.data
我尝试将所有计算进行组合并汇总,但是计算将在各自的列中返回。
data <- data.frame(id1 = 1:10,id3 = 1:10)
map.fun <- list(
innprod = ~ t(.x)%*%.x,identity = ~ sum(.x),range = ~ max(.x) - min(.x)
)
feat_m <- data %>% summarise(across(where(is.numeric),map.fun))
feat_m
解决方法
您为map.fun
设计的函数返回一个inprod
的矩阵,我们首先需要将其转换为向量,就像其余元素一样。
map.fun <- list(
innprod = ~ c(t(.x)%*%.x),identity = ~ sum(.x),range = ~ max(.x) - min(.x)
)
执行此操作后,可以使用summarise
+ across
将函数应用于每个数字列。如果要将每个值都放在单独的列中,则可以对带有pivot_longer
参数的汇总数据使用names_sep
。
library(dplyr)
data %>%
summarise(across(where(is.numeric),map.fun)) %>%
tidyr::pivot_longer(cols = where(is.numeric),names_to = c('id','.value'),names_sep = '_')
# id innprod identity range
# <chr> <dbl> <int> <int>
#1 id1 385 55 9
#2 id2 385 55 9
#3 id3 385 55 9
,
我们可以将其整形为'long'格式,然后作为函数应用
#include<stdio.h>
#include "mymalloc.h"
int main(){
int *p=(int*)MyMalloc(100*sizeof(int));
char *q=(char*)MyMalloc(250*sizeof(char));
int *r=(int*)MyMalloc(1000*sizeof(int));
MyFree(p);
char *w=(char*)MyMalloc(700);
MyFree(r);
int *k=(int*)MyMalloc(500*sizeof(int));
printf("Allocation and deallocation is done successfully!");
}
-输出
library(dplyr)
library(tidyr)
map.fun <- function(.x) list(
innprod = as.numeric(t(.x)%*%.x),identity = sum(.x),range = max(.x) - min(.x)
)
data %>%
select(where(is.numeric)) %>%
pivot_longer(everything()) %>%
group_by(name) %>%
summarise(value = list(map.fun(value)),.groups = 'drop') %>%
unnest_wider(c(value))
,
Base R替代方案,本质上是一个隐藏的双循环。仍可根据要求对许多功能进行概括:
funs <- c(
innprod = function(x) c(t(x) %*% x),identity = sum,range = function(x) diff(range(x))
)
sapply(funs,function(f) sapply(data,function(d) f(d)) )
# innprod identity range
#id1 385 55 9
#id2 385 55 9
#id3 385 55 9
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。