使用id值对两个数据帧执行逐元素计算

时间:2015-05-10 01:22:12

标签: r

我在两个数据帧上进行逐元素计算,但只在两组数据中存在相同的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值来验证/确保正在正确的行上进行计算。数据列?

3 个答案:

答案 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()增加了可读性。有很多方法可以做到这一点。很多很棒的库,比如plyrsqldf,可以让它变得简单。我期待在答案中看到更多的R-er方式。