我正在尝试编写一个返回数据帧的函数。基本上,目标是有三列:一列列出某个标识符,一列报告该标识符在数据集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))
我们可以用table
和merge
以更简单的方式实现这一点,而无需循环或使用任何外部包。我们只需要第一个数据集的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))