根据第二个data.frame中的因子水平对data.frame进行子集

时间:2019-06-24 13:45:55

标签: r

我有两个data.frames:

df.1 <- data.frame(A=runif(10), B=runif(10), C=runif(10), D=runif(10))
df.2 <- data.frame(Var=factor(c("A", "B", "C", "D")), Info=c("X1", "X2", "X1", "X2"))

df.1中,我要选择与df.2$Info中的一个因子水平相关的所有列

我只能通过非常笨拙的方式来做到这一点,首先将两个data.frames合并,然后进行子集设置,然后重新整理所需的输出:

tmp <- as.data.frame(t(df.1))
tmp$Var=row.names(tmp)
tmp.m <- merge(tmp, df.2, by="Var")

df.X1 <- tmp.m[tmp.m$Info == "X1", ]
df.X1$Info <- factor(df.X1$Info) # drop unused factor levels

desired.output <- as.data.frame(t(df.X1))
names(desired.output) <- lapply(desired.output[1, ], as.character)
desired.output <- desired.output[-c(1,11),] 

我的问题是,是否有更好,更快和更简单的方法(我敢肯定!)。谢谢。

4 个答案:

答案 0 :(得分:1)

您可以拆分和子集化,即

lapply(split(df.2$Var, df.2$Info), function(i) df.1[i])

给出,

$X1
           A          C
1  0.4666410 0.24030906
2  0.3246221 0.55153654
3  0.2042521 0.75376685
4  0.1130009 0.03761851
5  0.9979631 0.77633112
6  0.3611264 0.61717196
7  0.1535525 0.89337225
8  0.7068574 0.92468517
9  0.6951691 0.33549641
10 0.1637878 0.70826630

$X2
            B          D
1  0.06560149 0.24576981
2  0.23798129 0.53494840
3  0.62587837 0.08097668
4  0.38462826 0.98415256
5  0.94772413 0.85647140
6  0.90655926 0.97475473
7  0.48175364 0.24743947
8  0.65016599 0.75966646
9  0.19430794 0.82114764
10 0.97282206 0.19113057

答案 1 :(得分:1)

df.1[,unique(df.2$Var[which(df.2$Info=="X1")])]

           A            C
1  0.8924861 0.7149490854
2  0.5711894 0.7200819517
3  0.7049629 0.0004052017
4  0.9188677 0.5007302717
5  0.3440664 0.9138259818
6  0.8657903 0.2724015017
7  0.7631228 0.5686033906
8  0.8388003 0.7377064163
9  0.0796059 0.6196693045
10 0.5029824 0.8717568610

答案 2 :(得分:1)

我们还可以遍历“信息”列中的unique元素,与“信息”进行比较,提取“ Var”元素和子集

lapply(unique(df.2$Info), function(nm) df.1[df.2$Var[df.2$Info == nm]])

答案 3 :(得分:1)

一种tidyverse解决方案,可能不如其他解决方案那么优雅,但可以带来其他可能性:

library(tidyverse)
df.2sub <- df.2 %>% 
  filter(Info == "X1")

df.1sub <- df.1 %>% 
  select_if(colnames(.) %in% df.2sub$Var)


df.1sub

    A         C
1  0.99561926 0.6661509
2  0.68340388 0.5952997
3  0.21700589 0.6677539
4  0.07276628 0.2027971
5  0.70201107 0.4015561
6  0.86886930 0.7653709
7  0.71247007 0.1007955
8  0.96024317 0.7130610
9  0.04268316 0.9754990
10 0.67787175 0.8897161

编辑:

tidyverse有一个更简单的方法:

df.1sub <- df.1 %>% 
  select_if(colnames(.) %in% filter(df.2, Info == "X1")[["Var"]])