2015-08-08 73 views
1

如何在data.frame中使用一个变量来引用另一个变量?使用data.frame中的列来选择另一个

说我有:

col  col1  col2 
"col1" 1  5 
"col2" 2  6 
"col1" 3  7 
"col2" 4  8 

,我想:

col  col1  col2  answer 
"col1" 1  5   1 
"col2" 2  6   6 
"col1" 3  7   3 
"col2" 4  8   8 

df$answer = df[,df$col] 

不工作,和一个for循环永远走。

+0

我怎么样s的答案确定了吗? – vaettchen

+0

它是由df $ col – OldMcFartigan

+0

df $ answer = unlist(lapply(1:(dim(df)[1])),function(idx)df [idx,df [,df $ col [idx]]))似乎工作,但也许有更好的? – OldMcFartigan

回答

3

我知道这已经回答了,但我想另一种方法可能是有用的:

read.table(text='col  col1  col2 
"col1" 1  5 
"col2" 2  6 
"col1" 3  7 
"col2" 4  8',h=T)->df 

df$answer <- as.integer(df[ cbind(c(1:nrow(df)), match(df$col, names(df))) ]) 
df 
# col col1 col2 answer 
# 1 col1 1 5  1 
# 2 col2 2 6  6 
# 3 col1 3 7  3 
# 4 col2 4 8  8 
+0

这就是基本的惯用R答案。 –

3

这看起来不太难,但我发现的解决方案不是很优雅,有可能是更好的方法。

dat <- read.table(text="col  col1  col2 
col1 1  5 
col2 2  6 
col1 3  7 
col2 4  8", header = T, stringsAsFactors = FALSE) 

cols <- unique(dat$col) 
matches <- match(dat$col, cols) 

dat$answer <- sapply(seq_along(matches), function (i) { 
    dat[i,cols[matches[i]]] 
}) 

而结果::不过你可以根据比赛使用match,然后子集

> dat 
    col col1 col2 answer 
1 col1 1 5  1 
2 col2 2 6  6 
3 col1 3 7  3 
4 col2 4 8  8 

编辑

其实,这里是一个已经更好的方法:

dat$answer <- sapply(1:nrow(dat), function(r) { 
    dat[r,dat$col[r]] 
}) 

这显然是你已经尝试过,但使用sapply,而不是unlist(lapply,所以是的,不知道这是否有帮助。

1

在这种情况下,只有2列ifelse可能是最快,最简单的解决方案。

df$answer <- ifelse(df[,1] == "col1",df[,"col1"],df[,"col2”]) 

     col col1 col2 answer 
1 col1 1 5  1 
2 col2 2 6  6 
3 col1 3 7  3 
4 col2 4 8  8 

加为N8TRO在他的评论问一个更通用的解决方案。 简单switch可能是所有需要:

for(i in 1:nrow(df)) df$ans[i] <- switch(df[i,1],df[i,df[i,1]]) 

或不具有 “for” 循环:

df$ans <- sapply(1:nrow(df),function(i) switch(df[i,1],df[i,df[i,1]])) 

例如:

df <- data.frame(col=sample(paste0('col',1:5),10,replace=T),col1=1:10,col2=11:20,col3=21:30,col4=31:40,col5=41:50,stringsAsFactors = F) 

选择的元素:

df$ans <- sapply(1:nrow(df),function(i) switch(df[i,1],df[i,df[i,1]])) 

df 
    col col1 col2 col3 col4 col5 ans 
1 col1 1 11 21 31 41 1 
2 col1 2 12 22 32 42 2 
3 col5 3 13 23 33 43 43 
4 col2 4 14 24 34 44 14 
5 col3 5 15 25 35 45 25 
6 col4 6 16 26 36 46 36 
7 col5 7 17 27 37 47 47 
8 col3 8 18 28 38 48 28 
9 col1 9 19 29 39 49 9 
10 col5 10 20 30 40 50 50 
+0

我会upvote,但如果有'col3'怎么办? – N8TRO

+0

@ N8TRO,看看我的编辑更通用的解决方案。 – hvollmeier

+0

我喜欢它。开关是一个非常强大的功能,是其他2个答案的很好选择。 – N8TRO

相关问题