2017-06-05 200 views
1

的同一行的价值这个问题是相似,我在这里找到:Multiply rows (with row names) in one data frame with matching column names in another匹配行值返回DF2

但与其匹配的行和乘法,我想匹配列的值从df1以df2中的列名称返回,并在新的df3中返回相应的df2行值。

df1 <- data.frame(V1=c(1:6),V2=c("X3", "X3_8", "NA", "X5", "X4_5", "X3_8")) 
df1 
    V1 V2 
    1 1 X3 
    2 2 X3_8 
    3 3 NA 
    4 4 X5 
    5 5 X4_5 
    6 6 X3_8 

df2 <- data.frame(name=c("John", "Mary", "Joe", "Tim", "Bob", "Pat"), 
        X3=c(0.5, 1.2, 0.75, 3.1, 2.0, 1.1), 
        X5=c(1.0, 2.3, 4.2, 5, 1.1, 3.0), 
        X3_8=c(0.6, 1.0, 2.0, 1.0, 0.7, 1.4), 
        X4_5=c(0.4, 0.3, 3.0, 1.0, 2.0, 0.9)) 
df2 
    name X3 X5 X3_8 X4_5 
    1 John 0.5 1.0 0.6 0.4 
    2 Mary 1.2 2.3 1.0 0.3 
    3 Joe 0.75 4.2 2.0 3.0 
    4 Tim 3.1 5.0 1.0 1.0 
    5 Bob 2.0 1.1 0.7 2.0 
    6 Pat 1.1 3.0 1.4 0.9 

这就是我想要的:

df3 <- data.frame(name=c("John", "Mary", "Joe", "Tim", "Bob", "Pat"), 
        values=c(0.5, 1.0, NA, 5.0, 1.0, 1.4)) 
    name values 
    1 John 0.5 
    2 Mary 1.0 
    3 Joe  NA 
    4 Tim 5.0 
    5 Bob 1.0 
    6 Pat 1.4  

在我真正的DF1和DF2有64行,其中“V1”在DF1对应一个数字指标在DF2“名称”列。在我的df2中,有22列,即一个带有“name”,另一个带有“X *”的21个与df1中的“V2”匹配。我尝试将“V2”转换为行名,但这不起作用,因为有NA和重复值。

奖励但不是必需的:我有10个df1s和10个df2s,需要为df1s和df2s中的每个df1s和df2s的名称都包含常用年份。例如,我需要将df1_2004与df2_2004匹配,创建df3_2004,然后转到df1_2005和df2_2005,依此类推。我敢肯定,没有for循环和if语句,这是一个很好的方法。

感谢您的任何援助。我确信有一个简单的基本R或tidyrverse解决方案,但我很努力把这些部分放在一起。请原谅我对R中索引的新手理解。

+0

在你想要的解决方案中,不应该排第5,鲍勃,有2.0,而不是1.0? – G5W

+0

@ G5W好的。是的,它应该是2.0而不是1.0。 –

回答

0

df2重新整形为长格式并将左连接与df1相结合,您可以获得理想的结果。

使用:

library(dplyr) 
library(tidyr) 

df3 <- df1 %>% 
    mutate(name = df2$name[V1]) %>% # or just mutate(name = df2$name) when the index is equal to the rownumbers 
    left_join(., df2 %>% 
       gather(V2, values, -1) %>% 
       group_by(V2) %>% 
       mutate(V1 = row_number()), 
      by = c('V2','V1')) %>% 
    select(name = name.x, values) 

给出:

> df3 
    name values 
1 John 0.5 
2 Mary 1.0 
3 Joe  NA 
4 Tim 5.0 
5 Bob 2.0 
6 Pat 1.4 
+0

这很好用!两个注意事项:(1)在我的真实数据中,我必须在第一次mutate调用中对df2 $ name [1:64]进行索引; (2)我在选择函数中将“name.x”更改为“name”,因为它找不到“name.x”。我想这两者都与我真实数据中的细微差别相关联。谢谢。 –

0

世界的功能少的程序:

n_row <- nrow(df1) 
# corce the variable V1 in a factor with the name variables of the 
# df2 
df1$V1 <- factor(df1$V1, labels = df2$name) 
# coerce the variable V2 into a character vector or use 'stringsAsFactors = FALSE' 
# when you read the data frame 
df1$V2 <- as.character(df1$V2) 
# create a copy of df1 to impute values of the V2 col 
df3 <- df1 
for (i in 1:n_row) { 
    col_index <- which(df1[i, "V2"] == names(df2), arr.ind = TRUE) 
    row_index <- which(df1[i, "V1"] == df2$name, arr.ind = TRUE) 
    if (length(col_index) == 0) { 
    df3[i, "V2"] <- NA 
    } else { 
    df3[i, "V2"] <- df2[row_index, col_index] 
    } 
} 
names(df3) <- c("name", "values") 

给出:

#>df3 
    name values 
1 John 0.5 
2 Mary 1 
3 Joe <NA> 
4 Tim 5 
5 Bob 2 
6 Pat 1.4 
+0

这也适用,但Jaap的答案更接近我所寻找的。谢谢。 –