R 在 2 个列表中的匹配元素上迭代一个函数
R iterate a function over the matching elements in 2 lists
所以我尝试对列表中的每个元素(数据框)执行 Kmeans 聚类,从 kmeans 聚类的输出中,我采用了匹配每个数据框的“中心”并将所有中心绑定到另一个列表。
接下来,我要做的是使用函数 get.knnx(),这样我就可以使用由 kmeans 聚类生成的每个中心,并返回到原始数据帧来采样 500 个数据点离中心最近的那些,以实现对数据的良好子采样。 (我没有使用分配的 kmeans 聚类成员资格的原因是因为执行 kmeans 的数据只是用于训练的原始数据集的子采样)
每个dataframe的结构都是一样的:很多行样本,107列变量,但是第一列和第二列只是数据标签,比如实际的药物治疗。
这里是link对2个样本数据
https://drive.google.com/drive/folders/1B8JQY94Z-BHTZEKlV4dvUDocmiyppBDa?usp=sharing
library(tidyverse)
library(purr)
#take data into list
mylist <- list(df1,df2,df3...)
#perform Kmeans cluster
#scale datainput and drop the data label column
Kmeans.list <- map(.x = mylist,
.f = ~kmeans(scale(.x[,-c(1:2)]),
centers =15,
nstart=50,
iter.max = 100)) %>%
purrr::set_names(c("df1", "df2"))
#Isolate the Centers info to another list
Kmeans_centers <- map(Kmeans.list, ~.x$centers)
#trying to use map2
y <- map2(.x = mylist,.y=Kmeans_centers,
.f=~get.knnx(scale(.x[,-c(1:2)],.y, 500)))
感谢 Whosebug 上的传奇人物的帮助,我设法使 kmeans 工作并获得中心列表。现在我想使用相同的逻辑来使用 map2()
现在我从 map2 得到的错误是“scale.default(.x[ -c(1:2)], .y, 500) 中的错误:
'center' 的长度必须等于 'x'"
的列数
但是,两个列表都有7个元素,我不太清楚哪里出了问题。
另一个问题是关于 .f= 参数中的 ~ 。我读到如果我有一个函数输入,我不需要添加 ~,但是,在这种情况下,如果我删除 ~,错误说找不到 x。那么为什么这里需要 ~ ,我应该总是把 ~ 放在我放在 map() 参数中的函数前面吗?
您应该只对数据框应用 scale
函数。
library(purrr)
library(FNN)
map2(.x = mylist,.y=Kmeans_centers, .f=~get.knnx(scale(.x[,-c(1:2)]),.y, 500))
~
是一种基于公式的语法,用于应用函数,其中第一个参数称为 .x
,第二个参数称为 .y
。它是使用匿名函数的替代方法,可以写成
map2(.x = mylist,.y=Kmeans_centers, function(a, b) get.knnx(scale(a[,-c(1:2)]),b, 500))
所以我尝试对列表中的每个元素(数据框)执行 Kmeans 聚类,从 kmeans 聚类的输出中,我采用了匹配每个数据框的“中心”并将所有中心绑定到另一个列表。
接下来,我要做的是使用函数 get.knnx(),这样我就可以使用由 kmeans 聚类生成的每个中心,并返回到原始数据帧来采样 500 个数据点离中心最近的那些,以实现对数据的良好子采样。 (我没有使用分配的 kmeans 聚类成员资格的原因是因为执行 kmeans 的数据只是用于训练的原始数据集的子采样)
每个dataframe的结构都是一样的:很多行样本,107列变量,但是第一列和第二列只是数据标签,比如实际的药物治疗。
这里是link对2个样本数据 https://drive.google.com/drive/folders/1B8JQY94Z-BHTZEKlV4dvUDocmiyppBDa?usp=sharing
library(tidyverse)
library(purr)
#take data into list
mylist <- list(df1,df2,df3...)
#perform Kmeans cluster
#scale datainput and drop the data label column
Kmeans.list <- map(.x = mylist,
.f = ~kmeans(scale(.x[,-c(1:2)]),
centers =15,
nstart=50,
iter.max = 100)) %>%
purrr::set_names(c("df1", "df2"))
#Isolate the Centers info to another list
Kmeans_centers <- map(Kmeans.list, ~.x$centers)
#trying to use map2
y <- map2(.x = mylist,.y=Kmeans_centers,
.f=~get.knnx(scale(.x[,-c(1:2)],.y, 500)))
感谢 Whosebug 上的传奇人物的帮助,我设法使 kmeans 工作并获得中心列表。现在我想使用相同的逻辑来使用 map2()
现在我从 map2 得到的错误是“scale.default(.x[ -c(1:2)], .y, 500) 中的错误: 'center' 的长度必须等于 'x'"
的列数但是,两个列表都有7个元素,我不太清楚哪里出了问题。
另一个问题是关于 .f= 参数中的 ~ 。我读到如果我有一个函数输入,我不需要添加 ~,但是,在这种情况下,如果我删除 ~,错误说找不到 x。那么为什么这里需要 ~ ,我应该总是把 ~ 放在我放在 map() 参数中的函数前面吗?
您应该只对数据框应用 scale
函数。
library(purrr)
library(FNN)
map2(.x = mylist,.y=Kmeans_centers, .f=~get.knnx(scale(.x[,-c(1:2)]),.y, 500))
~
是一种基于公式的语法,用于应用函数,其中第一个参数称为 .x
,第二个参数称为 .y
。它是使用匿名函数的替代方法,可以写成
map2(.x = mylist,.y=Kmeans_centers, function(a, b) get.knnx(scale(a[,-c(1:2)]),b, 500))