R:通过一列数据帧进行分组/循环
我在R中有一个数据帧df,这里是它的前6行R:通过一列数据帧进行分组/循环,r,loops,dataframe,R,Loops,Dataframe,我在R中有一个数据帧df,这里是它的前6行 df <- data.frame (npi_one = c('n1487','n1952','n1952','n1467','n1467','n1538'), npi_two = c('n1467','n1467','n1487','n1508','n1538','n1508'), weight = c(1,1,2,1,1,1), hee_
df <- data.frame (npi_one = c('n1487','n1952','n1952','n1467','n1467','n1538'),
npi_two = c('n1467','n1467','n1487','n1508','n1538','n1508'),
weight = c(1,1,2,1,1,1),
hee_provn1=c(rep(015171,3),rep(015443,3)))
第二个循环hee_provn1==015171的结果表为
hee_provn1 npi degree closeness betweenness eigen
1: 15171 n1487 2 0.3333333 0.0 1.0000000
2: 15171 n1467 2 0.5000000 0.5 0.7320508
3: 15171 n1952 2 0.3333333 0.0 1.0000000
hee_provn1 npi degree closeness betweenness eigen
1: 15443 n1467 2 0.5 0 1
2: 15443 n1508 2 0.5 0 1
3: 15443 n1538 2 0.5 0 1
我是R新手,我不知道如何根据dataframe的一列进行分组和循环
另外,我希望我的最终结果是一个大表格,将所有表格放在一起,如:
hee_provn1 npi degree closeness betweenness eigen
1: 15171 n1487 2 0.3333333 0.0 1.0000000
2: 15171 n1467 2 0.5000000 0.5 0.7320508
3: 15171 n1952 2 0.3333333 0.0 1.0000000
4: 15443 n1467 2 0.5 0 1
5: 15443 n1508 2 0.5 0 1
6: 15443 n1538 2 0.5 0 1
由于某些原因,我不能使用R软件包tidyverse,谢谢
我从Balter那里试过这个方法
df <- data.frame (npi_one = c('n1487','n1952','n1952','n1467','n1467','n1538'),
npi_two = c('n1467','n1467','n1487','n1508','n1538','n1508'),
weight = c(1,1,2,1,1,1),
hee_provn1=c(rep(015171,3),rep(015443,3)))
library(igraph)
library(dplyr)
library(data.table)
final.df <- c()
for(x in unique(df$hee_provn1)){
df2 <- subset(df, subset = hee_provn1 == x)
df3 <- df2 [,c("npi_one","npi_two")]
l = c(apply(df3,1,c))
G <- graph(l,directed = FALSE)
d <- degree(G)
c <- closeness(G,weight = df2$weight)
b <- betweenness(G, weight = df2$weight)
e <- eigen_centrality(G,weight = df2$weight)$vector
result <- data.frame(d,c,b,e)
setDT(result, keep.rownames = TRUE)[]
setnames(result,1,"npi")
cbind(hee_provn1 = x,result)
final.df <- rbind(final.df, result)
}
colnames(final.df) <- c('npi','degree', 'closeness','betweenness','eigen')
看起来它与我的理想结果不同,如何成功地跟踪迭代产生它的原因?我能想到的最简单的方法是不重新创建整个代码:
final.df <- c()
for(x in unique(df$hee_provn1)){
y <- subset(df, subset = hee_provn1 == x)
result <- ##do your stuff here with table y
final.df <- rbind(final.df, result)
}
因此,您可以为hee_provn1中的每个唯一值对表进行子集设置,完成您的工作,然后将结果附加到一个数据框中。我可以想到的最简单的方法是不重新创建整个代码:
final.df <- c()
for(x in unique(df$hee_provn1)){
y <- subset(df, subset = hee_provn1 == x)
result <- ##do your stuff here with table y
final.df <- rbind(final.df, result)
}
因此,您可以在hee_provn1中为每个唯一值对表进行子集设置,完成您的工作,然后将结果附加到数据框中。不加载dplyr,重新开始。然后
library(data.table)
library(igraph)
setDT(df)
# clean bad formatting
df[, `:=`(npi_one = as.character(npi_one), npi_two = as.character(npi_two))]
df[, {
G = graph_from_edgelist(cbind(npi_one, npi_two), directed = FALSE)
.(
v = V(G)$name,
d = degree(G),
c = closeness(G, weight = weight),
b = betweenness(G, weight = weight),
e = eigen_centrality(G, weight = weight)$vector
)
}, by=hee_provn1]
这给了
hee_provn1 v d c b e
1: 15171 n1487 2 0.3333333 0.0 1.0000000
2: 15171 n1467 2 0.5000000 0.5 0.7320508
3: 15171 n1952 2 0.3333333 0.0 1.0000000
4: 15443 n1467 2 0.5000000 0.0 1.0000000
5: 15443 n1508 2 0.5000000 0.0 1.0000000
6: 15443 n1538 2 0.5000000 0.0 1.0000000
工作原理
Data.table语法是DT[i,j,by=],它按此处不需要的i过滤,按=分组,然后计算j。j应评估为一个列表,列表可以写成。作为速记
为什么不加载dplyr?不需要它,而且igraph已经有足够多的名称空间冲突
如果您真的想使用dplyr,我强烈建议不要同时使用data.table
library(dplyr)
library(magrittr)
library(igraph)
# fix bad formatting
df %<>% mutate(npi_one = as.character(npi_one), npi_two = as.character(npi_two))
df %>% group_by(hee_provn1) %>% do(with(., {
G = graph_from_edgelist(cbind(npi_one, npi_two), directed = FALSE)
data.frame(
v = V(G)$name,
d = degree(G),
c = closeness(G, weight = weight),
b = betweenness(G, weight = weight),
e = eigen_centrality(G, weight = weight)$vector
)
}))
# A tibble: 6 x 6
# Groups: hee_provn1 [2]
hee_provn1 v d c b e
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 15171 n1487 2 0.3333333 0.0 1.0000000
2 15171 n1467 2 0.5000000 0.5 0.7320508
3 15171 n1952 2 0.3333333 0.0 1.0000000
4 15443 n1467 2 0.5000000 0.0 1.0000000
5 15443 n1508 2 0.5000000 0.0 1.0000000
6 15443 n1538 2 0.5000000 0.0 1.0000000
在不加载dplyr的情况下重新启动。然后
library(data.table)
library(igraph)
setDT(df)
# clean bad formatting
df[, `:=`(npi_one = as.character(npi_one), npi_two = as.character(npi_two))]
df[, {
G = graph_from_edgelist(cbind(npi_one, npi_two), directed = FALSE)
.(
v = V(G)$name,
d = degree(G),
c = closeness(G, weight = weight),
b = betweenness(G, weight = weight),
e = eigen_centrality(G, weight = weight)$vector
)
}, by=hee_provn1]
这给了
hee_provn1 v d c b e
1: 15171 n1487 2 0.3333333 0.0 1.0000000
2: 15171 n1467 2 0.5000000 0.5 0.7320508
3: 15171 n1952 2 0.3333333 0.0 1.0000000
4: 15443 n1467 2 0.5000000 0.0 1.0000000
5: 15443 n1508 2 0.5000000 0.0 1.0000000
6: 15443 n1538 2 0.5000000 0.0 1.0000000
工作原理
Data.table语法是DT[i,j,by=],它按此处不需要的i过滤,按=分组,然后计算j。j应评估为一个列表,列表可以写成。作为速记
为什么不加载dplyr?不需要它,而且igraph已经有足够多的名称空间冲突
如果您真的想使用dplyr,我强烈建议不要同时使用data.table
library(dplyr)
library(magrittr)
library(igraph)
# fix bad formatting
df %<>% mutate(npi_one = as.character(npi_one), npi_two = as.character(npi_two))
df %>% group_by(hee_provn1) %>% do(with(., {
G = graph_from_edgelist(cbind(npi_one, npi_two), directed = FALSE)
data.frame(
v = V(G)$name,
d = degree(G),
c = closeness(G, weight = weight),
b = betweenness(G, weight = weight),
e = eigen_centrality(G, weight = weight)$vector
)
}))
# A tibble: 6 x 6
# Groups: hee_provn1 [2]
hee_provn1 v d c b e
<dbl> <chr> <dbl> <dbl> <dbl> <dbl>
1 15171 n1487 2 0.3333333 0.0 1.0000000
2 15171 n1467 2 0.5000000 0.5 0.7320508
3 15171 n1952 2 0.3333333 0.0 1.0000000
4 15443 n1467 2 0.5000000 0.0 1.0000000
5 15443 n1508 2 0.5000000 0.0 1.0000000
6 15443 n1538 2 0.5000000 0.0 1.0000000
我尝试了你的方法,很酷,我在问题中更新了它,但我仍然不知道如何跟踪哪个迭代产生了结果。thanksI评论了您的原始问题:我已经在OP下对此进行了评论,但您可能想看看R地狱的第2章。这可能违反直觉,但在使用R编程时记住这一点很有用。我尝试了您的方法,很酷,我在问题中对其进行了更新,但我仍然不知道如何跟踪哪个迭代产生了结果。thanksI评论了您的原始问题:我已经在OP下对此进行了评论,但您可能想看看R地狱的第2章。这可能违反直觉,但在使用R编程时请记住这一点。您只需在结果中添加一列即可。结果仅供参考,您的cbindhee_provn1=x,结果行没有任何作用。您需要分配结果。只有特殊的set*函数在不指定结果的情况下工作。此外,在循环中动态地增长东西在R中效率很低。R地狱是一个很好的陷阱指南,您可以在结果中添加一列。结果仅供参考,您的cbindhee_provn1=x,结果行没有任何作用。您需要分配结果。只有特殊的set*函数在不指定结果的情况下工作。另外,在循环中动态增长东西在R中效率很低。R地狱是一个很好的陷阱指南嗨,弗兰克,如果可能的话,你能用dplyr给我看看代码吗?@kkjoe好的,补充道。谢谢你,弗兰克。对不起,我刚发现我们的结果不一样。如果你看15443,n1467,你会发现你的贴近度是0.1666667,但是,你可以很容易地发现15543是一个三角形结构,所有的权重都是1,所以n1467的度量应该与n1538和n1508相同。我很努力地研究了你的代码,但是弄不懂why@kkjoe哦,对不起。我应该用edgelist的graph,而不是graph。我已经在邮局把它修好了,现在看起来很相配。谢谢你,先生,现在看起来很完美。我提出了一个新问题,它添加了一个新的需求—从另一个表中添加一些单个节点。您非常擅长r数据帧,如果您能帮助我使用dyplr,而不是loop,我将非常感激。非常感谢。嗨,弗兰克,如果可能的话,你能用dplyr给我看一下代码吗?@kkjoe好的,补充道。谢谢你,弗兰克。对不起,我刚发现我们的结果不一样。如果你看15443,n1467,你会发现你的贴近度是0.1666667,但是,你可以很容易地发现15543是一个三角形结构,所有的权重都是1,所以n1467的度量应该与n1538和n1508相同。我很努力地研究了你的代码,但是弄不懂why@kkjoe哦,对不起。我应该用edgelist的graph,而不是graph。我已经在邮局把它修好了,现在看起来很相配。谢谢你,先生,现在看起来很完美。我提出了一个新问题,它添加了一个新的需求—从另一个表中添加一些单个节点。您非常擅长r数据帧,如果您能帮助我使用dyplr,而不是loop,我将非常感激。非常感谢。