r-有没有一种方法可以让函数返回数据帧



我正在尝试编写一个返回数据帧的函数。基本上,目标是有三列:一列列出某个标识符,一列报告该标识符在数据集a的一列中出现的频率,另一列报告标识符在数据集中B的一列出现的频率。我写了这个函数,但不明白为什么它是打印而不是存储为数据帧。这尤其令人费解,因为当我运行";如果";在函数外循环,它会创建所需的数据帧。如有任何帮助,我们将不胜感激。

数据样本为:

UOF$identifier     Citations$identifier
1545               1712
1588               646
1640               1545
1545               1645
1545               646
1588               1545
1640
1640

我希望这个函数返回:

value    instances in dataset 1    instances in dataset 2
1545     3                         2
1588     2                         0
1640     1                         2
join_analysis<-function(column_name_fromdataset1, column_name_fromdataset2){
Dataset1<-as.numeric(column_name_fromdataset1)
Dataset2<-as.numeric(column_name_fromdataset2)
unique_values1<-unique(Dataset1)  
count<-data.frame(matrix(NA,nrow=length(Dataset2),ncol=3))
for (i in 1:length(unique_values1)){
ID<-unique_values1[i]
count[,3][i]<-sum(Dataset2==ID, na.rm = TRUE)
count[,2][i]<-sum(Dataset1==ID, na.rm=TRUE)
count[,1][i]<-unique_values1[i]
}
colnames(count)<-cbind("value","instances in dataset 1", "instances in dataset 2")
return(as.data.frame(count))
}

我建议使用dplyr方法和内置函数来避免循环。函数将两个参数作为字符串,它们属于每个数据集中的列名。之后,它合并结果:

library(dplyr)
#Function
myfun <- function(x,y)
{
#Dataset 1
r1 <- df1 %>% group_by(id=df1[,x]) %>% summarise(N1=n())
#Dataset 2
r2 <- df2 %>% group_by(id=df2[,y]) %>% summarise(N2=n())
#Join
r3 <- left_join(r1,r2)
#Fill
r3 %>% replace(is.na(.),0) -> r3
return(r3)
}
#Apply function
myfun(x = 'UOF',y = 'Identifier')

输出:

# A tibble: 3 x 3
id    N1    N2
<int> <int> <int>
1  1545     3     2
2  1588     2     0
3  1640     1     2

使用的一些数据:

#Data
df1 <- structure(list(UOF = c(1545L, 1588L, 1640L, 1545L, 1545L, 1588L
)), class = "data.frame", row.names = c(NA, -6L))
df2 <- structure(list(Identifier = c(1712L, 646L, 1545L, 1645L, 646L, 
1545L, 1640L, 1640L)), class = "data.frame", row.names = c(NA, 
-8L))

如果你想使用基本R ,也许你可以试试下面的merge+stack

merge(aggregate(. ~ ind, stack(table(UOF)), sum),
aggregate(. ~ ind, stack(table(Citations)), sum),
by = "ind", all.x = TRUE
)

它给出

ind values.x values.y
1 1545        3        2
2 1588        2       NA
3 1640        1        2

数据

UOF <- data.frame(identifier = c(1545, 1588, 1640, 1545, 1545, 1588))
Citations <- data.frame(identifier = c(1712, 646, 1545, 1645, 646, 1545, 1640, 1640))

我们可以用tablemerge以更简单的方式实现这一点,而无需循环或使用任何外部包。我们只需要第一个数据集的unique值,就可以使"标识符"列成为factor,并从第一个数据集中分配levels,得到table,然后进行merge(从base R(

join_analysis <- function(dat1, dat2, colnm1) {
lvls <- unique(dat1[[colnm1]])
tbl1 <- table(factor(dat1[[colnm1]], levels = lvls))
tbl2 <- table(factor(dat2[[colnm1]], levels = lvls))
out <- merge(tbl1, tbl2, by = 'row.names')[-c(1, 4)]
names(out) <- c('value', 'instances in dataset 1',  
'instances in dataset 2')
return(out)
}
join_analysis(UOF, Citations, 'identifier')
#   value instances in dataset 1 instances in dataset 2
#1  1545                      3                      2
#2  1588                      2                      0
#3  1640                      1                      2

或者另一个选项是pivot_wider

library(dplyr)
library(tidyr)
bind_rows(UOF, Citations, .id = 'grp') %>% 
filter(identifier %in% unique(UOF$identifier)) %>%
count(grp, identifier) %>% 
pivot_wider(names_from = grp, values_from = n, values_fill = 0)

或者另一个选项是在list中的两个数据集中执行count,然后使用left_join执行reduce

library(purrr)
list(UOF, Citations) %>%
map(~ .x %>%
count(identifier)) %>%
reduce(left_join, by = 'identifier')

数据

UOF <- structure(list(identifier = c(1545, 1588, 1640, 1545, 1545, 1588
)), class = "data.frame", row.names = c(NA, -6L))
Citations <- structure(list(identifier = c(1712, 646, 1545, 1645, 646, 1545, 
1640, 1640)), class = "data.frame", row.names = c(NA, -8L))

最新更新