将条件选择应用于列R的序列

时间:2016-03-06 18:59:22

标签: r for-loop conditional dplyr

我使用来自NHANES牙周数据集(https://wwwn.cdc.gov/Nchs/Nhanes/2009-2010/OHXPER_F.htm)的数据,并在清洁后仅保留" pc"变量,我有一个df = setPD 168列,包括6个测量值(pcd,pcm,pcs,pcp,pcl,pca),大约28个齿,编号从#02到#31

#names(setPD)
  [1] "ohx02pcd" "ohx02pcm" "ohx02pcs" "ohx02pcp" "ohx02pcl" "ohx02pca" "ohx03pcd" "ohx03pcm" "ohx03pcs" "ohx03pcp" "ohx03pcl" "ohx03pca"
 [13] "ohx04pcd" "ohx04pcm" "ohx04pcs" "ohx04pcp" "ohx04pcl" "ohx04pca" "ohx05pcd" "ohx05pcm" "ohx05pcs" "ohx05pcp" "ohx05pcl" "ohx05pca"
 [25] "ohx06pcd" "ohx06pcm" "ohx06pcs" "ohx06pcp" "ohx06pcl" "ohx06pca" "ohx07pcd" "ohx07pcm" "ohx07pcs" "ohx07pcp" "ohx07pcl" "ohx07pca"
 [37] "ohx08pcd" "ohx08pcm" "ohx08pcs" "ohx08pcp" "ohx08pcl" "ohx08pca" "ohx09pcd" "ohx09pcm" "ohx09pcs" "ohx09pcp" "ohx09pcl" "ohx09pca"
 [49] "ohx10pcd" "ohx10pcm" "ohx10pcs" "ohx10pcp" "ohx10pcl" "ohx10pca" "ohx11pcd" "ohx11pcm" "ohx11pcs" "ohx11pcp" "ohx11pcl" "ohx11pca"
 [61] "ohx12pcd" "ohx12pcm" "ohx12pcs" "ohx12pcp" "ohx12pcl" "ohx12pca" "ohx13pcd" "ohx13pcm" "ohx13pcs" "ohx13pcp" "ohx13pcl" "ohx13pca"
 [73] "ohx14pcd" "ohx14pcm" "ohx14pcs" "ohx14pcp" "ohx14pcl" "ohx14pca" "ohx15pcd" "ohx15pcm" "ohx15pcs" "ohx15pcp" "ohx15pcl" "ohx15pca"
 [85] "ohx18pcd" "ohx18pcm" "ohx18pcs" "ohx18pcp" "ohx18pcl" "ohx18pca" "ohx19pcd" "ohx19pcm" "ohx19pcs" "ohx19pcp" "ohx19pcl" "ohx19pca"
 [97] "ohx20pcd" "ohx20pcm" "ohx20pcs" "ohx20pcp" "ohx20pcl" "ohx20pca" "ohx21pcd" "ohx21pcm" "ohx21pcs" "ohx21pcp" "ohx21pcl" "ohx21pca"
[109] "ohx22pcd" "ohx22pcm" "ohx22pcs" "ohx22pcp" "ohx22pcl" "ohx22pca" "ohx23pcd" "ohx23pcm" "ohx23pcs" "ohx23pcp" "ohx23pcl" "ohx23pca"
[121] "ohx24pcd" "ohx24pcm" "ohx24pcs" "ohx24pcp" "ohx24pcl" "ohx24pca" "ohx25pcd" "ohx25pcm" "ohx25pcs" "ohx25pcp" "ohx25pcl" "ohx25pca"
[133] "ohx26pcd" "ohx26pcm" "ohx26pcs" "ohx26pcp" "ohx26pcl" "ohx26pca" "ohx27pcd" "ohx27pcm" "ohx27pcs" "ohx27pcp" "ohx27pcl" "ohx27pca"
[145] "ohx28pcd" "ohx28pcm" "ohx28pcs" "ohx28pcp" "ohx28pcl" "ohx28pca" "ohx29pcd" "ohx29pcm" "ohx29pcs" "ohx29pcp" "ohx29pcl" "ohx29pca"
[157] "ohx30pcd" "ohx30pcm" "ohx30pcs" "ohx30pcp" "ohx30pcl" "ohx30pca" "ohx31pcd" "ohx31pcm" "ohx31pcs" "ohx31pcp" "ohx31pcl" "ohx31pca"

我正在尝试在每组六列中应用条件选择。这是:

transmute(setPD,PD02 = ifelse(setPD$ohx02pcd >5 | 
    setPD$ohx02pcm>5 |setPD$ohx02pcs >5| 
    setPD$ohx02pcp >5 | setPD$ohx02pcl >5 | 
    setPD$ohx02pca >5, 1, 0))

然后对于下一颗牙齿(03)我必须再写一次:

transmute(setPD,PD03 = ifelse(setPD$ohx03pcd >5 |
   setPD$ohx03pcm>5|setPD$ohx03pcs >5|
   setPD$ohx03pcp >5|setPD$ohx03pcl >5|
   setPD$ohx03pca >5, 1, 0))

我首先尝试以更有效的方式进行条件选择,例如:

transmute(setPD,PD02 = ifelse(list(setPD$ohx02pcd:setPD$ohx02pcp) >5, 1, 0))

但它不起作用。

然后我正在寻找一种方法来编写一个循环,在每个牙齿上做这个,而不需要写28次!! 我想在for循环中应用dplyr的select函数,但我不知道该怎么做。 最后,我想得到我用转化制作的所有新专栏,并说如果28列中至少有2列是1,那么我就有疾病,如果< 2是1那么我就健康了。任何帮助,将不胜感激。

**注意:如果您想获取数据集,则可以从CDC.org进行开放访问: https://wwwn.cdc.gov/Nchs/Nhanes/2009-2010/OHXPER_F.htm **

1 个答案:

答案 0 :(得分:1)

首先,有必要指出is A true OR is B true OR is C true形式的逻辑语句等同于询问is ANY of A,B,C true?我们可以使用它来简化语句setPD$ohx02pcd >5 | setPD$ohx02pcm>5 |setPD$ohx02pcs >5| ...,以询问对于这些列中的任何一列,它们的值是否大于5。

例如,让我们首先关注02号牙齿。要获取与此关联有关的所有列,我们可以使用grep来获取列名称的向量。这可以通过

来实现
current_tooth <- grep("02", names(setPD), value = T)

请注意,如果数据中包含字符串02的任何其他列,则这些列也会显示。这似乎不是您的数据中的情况,但值得指出这里以防其他人使用它,这适用于其他数据集。

现在,我们可以使用这些名称来对数据帧进行子集化。例如,

 setPD[,current_tooth]

会给你相应的列。在每一行中,我们要检查上述任何条件是否为真。给定逻辑语句的向量,我们可以使用函数any检查它们中的任何一个是否为真。要逐行浏览数据并应用函数,我们可以使用apply,例如

setPD$PD02 <- 
  apply(setPD[,grep("02", names(setPD), value = T)], 1, function(x) any(x>5))

现在,上述仅适用于一颗牙齿,即02。对所有牙齿进行此操作的一种方法是创建一个包含所有牙齿指示符的向量,并使用它来遍历上述行,在每次迭代中替换上述"02"调用中的grep并使用{{ 1}}或类似的东西,使变量名称正确。更优雅,更有效的方法是在长数据上使用相同的原则。请考虑以下事项:

assign

这会先熔化您的数据并创建一个表示您的牙齿的变量library(reshape2) library(dplyr) m <- melt(setPD, id.vars="SEQN") m$num <- substr(m$variable, 4,5) # be careful here and check output! m <- m %>% group_by(num) %>% mutate(PS = any(value>5)) m$num <- paste0("PS", m$num) md <- dcast(m, SEQN ~ num, value.var = "PS") setPD <- merge(setPD, md, by="SEQN") 。再次,确保这是有效的。我使用的事实是,在您的数据中,齿数全部出现在字符串的第4和第5位。确保这是真的,否则调整代码。然后我创建一个变量num,它指示包含牙齿标识符的任何列是否具有大于5的值。最后但并非最不重要的是我重新设置数据,以便您具有PS的值在将此数据合并到旧数据集之前,再次列。 PD02, PD03, etc行只会创建您想要的变量名。