我有这样的df:
id <- c("defoo","ghfoo","abfoo")
abc <- c(.3,.1,.4)
ghi <- c(.4,.2,.2)
abc_dif <- c(.4,.3,.8)
def_dif <- c(.5,.7,.6)
ghi_dif <- c(.2,.1,.9)
df <- data.frame(id,abc,ghi,abc_dif,def_dif,ghi_dif)
我想查找名称中包含id行中值的前两个字符的列,并且还包括&#34; dif,&#34;并创建一个新列,其中包含每行的这些列中的相应值。
在此示例数据中,新列将是
df$result <- c(.5,.1,.8)
我的众多尝试涉及各种版本的sapply和apply,就像下面尝试简单地获取列索引一样:
df$result <- apply(substr(df[,which(colnames(df)=="id")],1,2),1,function(x) grep(x,colnames(df[which(grepl("dif",colnames(df),fixed=TRUE))]),fixed = TRUE))
这给出了错误:
"Error in apply(substr(df[, which(colnames(df) == "id")], 1, 2), 1, function(x) grep(x, : dim(X) must have a positive length"
这样做的最佳方式是什么?
答案 0 :(得分:2)
我们可以创建一个row/column
索引来获取值
df$result <- df[4:6][cbind(1:nrow(df), match( substr(df$id, 1, 2),
substr(names(df)[4:6], 1, 2)))]
df$result
#[1] 0.5 0.1 0.8
答案 1 :(得分:1)
您可以尝试tidyverse
library(tidyverse)
df %>%
gather(k,v, -id:-ghi) %>%
filter(str_sub(id,1,2) == str_sub(k,1,2)) %>%
select(1,result=v) %>%
left_join(df, .)
id abc ghi abc_dif def_dif ghi_dif result
1 defoo 0.3 0.4 0.4 0.5 0.2 0.5
2 ghfoo 0.1 0.2 0.3 0.7 0.1 0.1
3 abfoo 0.4 0.2 0.8 0.6 0.9 0.8
答案 2 :(得分:0)
您可以循环浏览df$id
,然后为每一个选择df
中的相关单元格:
df$result <- sapply(df$id, function(x) df[df$id == x,
grepl(paste0(substring(x,1,2),".*dif"), names(df))])
df$result
#[1] 0.5 0.1 0.8