繁体   English   中英

使用data.frame中的一列选择另一个

[英]Use a column in a data.frame to select another

如何在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循环将永远持续下去。

这看起来并不难,但是我发现的解决方案不是很好,可能有更好的方法。 但是您可以使用match然后根据match使用子集:

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]]]
})

结果:

> 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 ,所以是的,不确定是否有帮助。

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

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

在这种情况下,只有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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM