字符串作为公式

时间:2018-09-26 03:27:35

标签: r dplyr

我尝试搜索论坛,但找不到帮助。我对R很陌生,并且在加载一些用作公式的字符串方面取得的成功有限。

我的csv格式如下:

            Sam, Frank, Dennis, Steven, Robert, Georgia
Region_1    218,    763,    811,    812,    797,    574
Region_2    474,    983,    343,    697,    310,    335
Region_3    700,    813,    133,    212,    906,    680
Region_4    212,    581,    893,    514,    530,    795

并且能够将其加载到其中并在我的数据框中添加其他列以添加特定列(例如Sam + Frank,Dennis + Georgia)。

如果我将团队硬编码到我的代码中,我可以做到,例如:

temp <- mutate(temp, team_1 = Sam + Robert) 

我的问题是我还有一个csv,其中包含2列的列表,而这些团队每天都在变化,例如:

Team 1  Sam + Robert
Team 2  Frank + Georgia
Team 3  Frank + Steven
Team 4  Robert + Dennis
Team 5  Frank + Sam

有没有一种方法可以将此csv列表加载到R中并将这些团队成员列添加在一起。

但是我看不到从csv文件中添加此列表,并且没有动态包含团队成员总数的新数据框。

有人可以帮助我吗?

我希望最终得到这样的内容(团队成员的总和(第二个csv文件中的团队1,团队2等)作为附加列:

         Sam,   Frank,  Dennis, Steven, Robert, Georgia,    Sam + Robert,   Frank + Georgia,    Frank + Steven, Robert + Dennis,    Frank + Sam
 Region_1   218,    763,    811,    812,    797,    574,    981,    1337,   1575,   1608,   981
 Region_2   474,    983,    343,    697,    310,    335,    1457,   1318,   1680,   653,    1457
 Region_3   700,    813,    133,    212,    906,    680,    1513,   1493,   1025,   1039,   1513
 Region_4   212,    581,    893,    514,    530,    795,    793,    1376,   1095,   1423,   793

非常感谢。

4 个答案:

答案 0 :(得分:4)

将代码作为字符串使用是很复杂的。在这里,将第二个数据帧转换为查找表可以更简单,该查找表可以与第一个重塑为长形的表连接。然后可以将结果汇总并调整为您想要的任何形式。

library(tidyverse)

people <- data.frame(
    region = c("Region_1", "Region_2", "Region_3", "Region_4"),
    Sam = c(218L, 474L, 700L, 212L),
    Frank = c(763L, 983L, 813L, 581L),
    Dennis = c(811L, 343L, 133L, 893L),
    Steven = c(812L, 697L, 212L, 514L),
    Robert = c(797L, 310L, 906L, 530L),
    Georgia = c(574L, 335L, 680L, 795L), 
    stringsAsFactors = FALSE
)

teams <- data.frame(
    team = c("Team 1", "Team 2", "Team 3", "Team 4", "Team 5"),
    members = c("Sam + Robert", "Frank + Georgia", "Frank + Steven", "Robert + Dennis", "Frank + Sam"), 
    stringsAsFactors = FALSE
)

teams_long <- teams %>% 
    mutate(team = members) %>%    # set team name
    separate_rows(members)    # separate teams to names

people %>% 
    gather(member, value, -region) %>%    # reshape to long form
    left_join(teams_long, c('member' = 'members')) %>%    # join by names
    group_by(region, team) %>% 
    summarise(value = sum(value)) %>%    # aggregate
    spread(team, value) %>%    # reshape to wide form
    left_join(people, .)    # join back to original data
#>     region Sam Frank Dennis Steven Robert Georgia Frank + Georgia
#> 1 Region_1 218   763    811    812    797     574            1337
#> 2 Region_2 474   983    343    697    310     335            1318
#> 3 Region_3 700   813    133    212    906     680            1493
#> 4 Region_4 212   581    893    514    530     795            1376
#>   Frank + Sam Frank + Steven Robert + Dennis Sam + Robert
#> 1         981           1575            1608         1015
#> 2        1457           1680             653          784
#> 3        1513           1025            1039         1606
#> 4         793           1095            1423          742

答案 1 :(得分:3)

这里是使用node直接从第二个rlang::parse_expr解析表达式的选项

data.frame

或者您可以根据团队命名新列:

df1 %>% bind_cols(map_dfc(df2$V2, ~df1 %>%
    transmute(!!as.character(.x) := !!rlang::parse_expr(as.character(.x)))))
#  Sam Frank Dennis Steven Robert Georgia Sam + Robert Frank + Georgia
#1 218   763    811    812    797     574         1015            1337
#2 474   983    343    697    310     335          784            1318
#3 700   813    133    212    906     680         1606            1493
#4 212   581    893    514    530     795          742            1376
#  Frank + Steven Robert + Dennis Frank + Sam
#1           1575            1608         981
#2           1680             653        1457
#3           1025            1039        1513
#4           1095            1423         793

这个想法是我们使用df1 %>% bind_cols(map2_dfc(df2$V1, df2$V2, ~df1 %>% transmute(!!as.character(.x) := !!rlang::parse_expr(as.character(.y))))) # Sam Frank Dennis Steven Robert Georgia Team 1 Team 2 Team 3 Team 4 Team 5 #1 218 763 811 812 797 574 1015 1337 1575 1608 981 #2 474 983 343 697 310 335 784 1318 1680 653 1457 #3 700 813 133 212 906 680 1606 1493 1025 1039 1513 #4 212 581 893 514 530 795 742 1376 1095 1423 793 (或map)在map2的{​​{1}}上下文中应用存储在df2中的“公式”。表达式用transmute求值。


样本数据

df1

答案 2 :(得分:2)

背景:您可以使用unit8访问存储在向量x中的data.frame列,还可以使用people[, x]获取列的向量您需要。

答案

strsplit

答案 3 :(得分:2)

(感谢@alistaire以方便的格式对数据进行编码)

这可以通过简单的for循环中的基本R函数(eval + parse)轻松完成:

for(i in teams$members){
    people[[i]] <- eval(parse(text = i), envir = people)
}

# > people
#     region Sam Frank Dennis Steven Robert Georgia Sam + Robert Frank + Georgia
# 1 Region_1 218   763    811    812    797     574         1015            1337
# 2 Region_2 474   983    343    697    310     335          784            1318
# 3 Region_3 700   813    133    212    906     680         1606            1493
# 4 Region_4 212   581    893    514    530     795          742            1376
# Frank + Steven Robert + Dennis Frank + Sam
# 1           1575            1608         981
# 2           1680             653        1457
# 3           1025            1039        1513
# 4           1095            1423         793