[英]Subsetting a dataframe based on another dataframe in R
df: df:
y x
F T
F F
T T
T F
df1: df1:
y z probs.x x probs.y new
F F 0.08 T 0.4 0.032
F F 0.24 F 0.4 0.096
F T 0.12 T 0.6 0.072
F T 0.36 F 0.6 0.216
T F 0.40 T 0.5 0.200
T F 0.20 F 0.5 0.100
T T 0.40 T 0.5 0.200
T T 0.20 F 0.5 0.100
df and df1 are the two data frames. df和df1是两个数据帧。 And for each row of df, I want to select the matching rows in df1, add the values in column “new”, and store output in a new data frame like this. 对于df的每一行,我想在df1中选择匹配的行,在“ new”列中添加值,并将输出存储在这样的新数据框中。
df_res: df_res:
y x new
F T .104
F F .312
T T .4
T F .2
Kindly help me out! 请帮我! I have been toiling over this for a long time now. 我已经为此花了很长时间了。 The table headers will change according to the variables, so please do do not hard code the table headers. 表头会根据变量而变化,因此请不要对表头进行硬编码。
Thanks. 谢谢。
I don't know how long is your data but this can be one approach. 我不知道您的数据多长时间,但这可以是一种方法。
df<- read.table(text="y x
F T
F F
T T
T F",header=T,sep="")
df1 <- read.table(text="y z probs.x x probs.y new
F F 0.08 T 0.4 0.032
F F 0.24 F 0.4 0.096
F T 0.12 T 0.6 0.072
F T 0.36 F 0.6 0.216
T F 0.40 T 0.5 0.200
T F 0.20 F 0.5 0.100
T T 0.40 T 0.5 0.200
T T 0.20 F 0.5 0.100", header=T, sep="")
df$yx <- paste0(df$y,df$x)
df1$yx <- paste0(df1$y, df1$x)
# Update automatically using the for loop
for (i in 1:4){
new[i] <- sum(df1[which(df1[,7]==df[i,3]),6])
}
df$new <- new
df
y x yx new
1 FALSE TRUE FALSETRUE 0.104
2 FALSE FALSE FALSEFALSE 0.312
3 TRUE TRUE TRUETRUE 0.400
4 TRUE FALSE TRUEFALSE 0.200
Using sapply 使用sapply
new <- sapply(1:4, function(x) sum(df1[which(df1[,7]==df[x,3]),6]))
it seems like if all you want is F,T combination. 好像你想要的只是F,T组合。 this works. 这可行。 otherwise you have to write more clearly. 否则,您必须写得更清楚。
text=" y z probs.x x probs.y new
F F 0.08 T 0.4 0.032
F F 0.24 F 0.4 0.096
F T 0.12 T 0.6 0.072
F T 0.36 F 0.6 0.216
T F 0.40 T 0.5 0.200
T F 0.20 F 0.5 0.100
T T 0.40 T 0.5 0.200
T T 0.20 F 0.5 0.100"
df<-read.table(text=text, header=T)
df_res<-aggregate(data=df, new~interaction(y,x),sum)
interaction(y, x) new
1 FALSE.FALSE 0.312
2 TRUE.FALSE 0.200
3 FALSE.TRUE 0.104
4 TRUE.TRUE 0.400
Here's an answer using merge and plyr . 这是使用merge和plyr的答案。
Read in your example data.frame : 读入示例data.frame :
df1 <- read.table(text="y z probs.x x probs.y new
F F 0.08 T 0.4 0.032
F F 0.24 F 0.4 0.096
F T 0.12 T 0.6 0.072
F T 0.36 F 0.6 0.216
T F 0.40 T 0.5 0.200
T F 0.20 F 0.5 0.100
T T 0.40 T 0.5 0.200
T T 0.20 F 0.5 0.100", header=T, sep="")
If I understand, there are 2 steps to what your asking. 据我了解,您的询问有两个步骤。 First is to select rows in df1 that match patterns in df. 首先是在df1中选择与df中的模式匹配的行。 That can be done with merge . 这可以通过merge来完成。 The df you gave has all combinations of True and False for x and y. 您给定的df对x和y具有True和False的所有组合。 Let's leave one out so we can see the effect: 让我们省略一个,以便我们看到效果:
df <- read.table(text="y x
F T
T T
T F",header=T,sep="")
df_merged <- merge(df, df1, all.y=F)
The results are a new data.frame the omits the rows where both x and y are F. This is equivalent to a left join in a SQL database. 结果是一个新的data.frame,省略了x和y均为F的行。这等效于SQL数据库中的左连接。
y x z probs.x probs.y new
1 FALSE TRUE FALSE 0.08 0.4 0.032
2 FALSE TRUE TRUE 0.12 0.6 0.072
3 TRUE FALSE FALSE 0.20 0.5 0.100
4 TRUE FALSE TRUE 0.20 0.5 0.100
5 TRUE TRUE FALSE 0.40 0.5 0.200
6 TRUE TRUE TRUE 0.40 0.5 0.200
The second part of the question is to group the data and apply a sum to the groups. 问题的第二部分是对数据进行分组并将总和应用于分组。 Plyr is a great tool for this kind of data manipulation: Plyr是用于这种数据处理的好工具:
library(plyr)
ddply(df_merged, .(y,x), function(df) c(new=sum(df$new)))
The dd means we are giving a data.frame and want a data.frame as a result. dd表示我们正在提供一个data.frame并希望有一个data.frame作为结果。 The next argument .(y,x) is a quoted expression and names the variables we're grouping by. 下一个参数。(y,x)是带引号的表达式,并命名要分组的变量。 The result is this: 结果是这样的:
y x new
1 FALSE TRUE 0.104
2 TRUE FALSE 0.200
3 TRUE TRUE 0.400
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.