我在两个数据帧上进行逐元素计算,但只在两组数据中存在相同的id。
我正在使用的当前方法是对存在相同ID的数据帧进行子集化,然后按id对数据进行排序,然后进行计算:
## Example data
id <- c('a','b','c','d','e')
v1 <- c(10, 20, 30,20,40)
v2 <- c(20,30,20,20,40)
df1 <- data.frame(id, v1, v2, stringsAsFactors=FALSE)
id <- c('a','c','d','b','f')
v1 <- c(20,60,30,10,20)
v2 <- c(60,20,50,10,20)
df2 <- data.frame(id, v1, v2, stringsAsFactors=FALSE)
## subset both data frames by ids that exist in both
df1_subset <- df[df1$id %in% df2$id,]
df2_subset <- df2[df2$id %in% df1$id,]
id <- df1_subset$id
## arrange by id value
library(dplyr)
df1_sorted <- df1_subset %>% arrange(id)
df2_sorted <- df2_subset %>% arrange(id)
## find the difference between each value
df_result <- cbind(id, df2_sorted[,2:3] - df1_sorted[,2:3])
在数据不需要的情况下进行此计算是否有“更好”的方法 作为子集和排序,并直接使用id值来验证/确保正在正确的行上进行计算。数据列?
答案 0 :(得分:3)
您可以使用merge
然后使用单个transform
来执行您需要的操作:
#merge will find the common ids between the dataframes
a <- merge(df1,df2, by='id')
#transform will add the two columns you need (subtracting one from the other)
a <- transform(a, v1 = v1.y - v1.x, v2 = v2.y - v2.x)
输出:
> a
id v1.x v2.x v1.y v2.y v1 v2
1 a 10 20 20 60 10 40
2 b 20 30 10 10 -10 -20
3 c 30 20 60 20 30 0
4 d 20 20 30 50 10 30
与df_result
> df_result
id v1 v2
1 a 10 40
2 b -10 -20
3 c 30 0
4 d 10 30
答案 1 :(得分:3)
library(dplyr)
inner_join(df1, df2, by="id") %>%
mutate(v1=v1.y-v1.x, v2=v2.y-v2.x) %>%
select(id, v1, v2)
# id v1 v2
#1 a 10 40
#2 b -10 -20
#3 c 30 0
#4 d 10 30
答案 2 :(得分:1)
首先,您可以使用merge()
(在R基础上)轻松加入ID上的这些DF:
df_merged = merge(df1,df2, by='id')
为您提供以下新列名称:
names(df_merged)
# [1] "id" "v1.x" "v2.x" "v1.y" "v2.y"
因为merge()
默认情况下会为碰撞列名添加后缀。
然后考虑这个组合来得到你的结果......
df_result = with(df_merged, data.frame(id, result1 = v1.x - v1.y, result2 = v2.x-v2.y)))
with()
增加了可读性。有很多方法可以做到这一点。很多很棒的库,比如plyr
和sqldf
,可以让它变得简单。我期待在答案中看到更多的R-er方式。