避免数据帧中的循环和数据类型错误

时间:2016-05-13 18:27:21

标签: r loops dataframe

您好我正在处理类似于以下内容的数据: -

df <- data.frame(Name=c("Joy","Jane"),M1=c(10,40),M2=c(25,35),Choice=c("M1","M2")

    Name   M1   M2  Choice
1   Joy    10   25     M1
2   Jane   40   35     M2


for (i in (1:length(df[,1]))){
  df$Final[i] <- as.character(df[i,df$Choice[i]])
}

Output :-

    Name   M1   M2   Choice Final
1   Joy    10   25     M1   Joy
2  Jane    40   35     M2    40

此输出错误,我发现这是因为 df $ Choice [i] 返回因子,因此我将其转换为字符并获得正确的输出。

for (i in (1:length(df[,1]))){
  df$Final[i] <- as.character(df[i,as.character(df$Choice[i])])
}

Output:- 

    Name   M1   M2 Choice Final
1    Joy   10   25     M1    10
2   Jane   40   35     M2    35

我的问题是,如何在较大的数据集上执行相同的操作,避免循环。如果我使用

df$Final <- as.character(df[,as.character(df$Choice)])  

Output:-


      Name   M1  M2   Choice     Final
1     Joy    10  25     M1     c(10, 40)
2     Jane   40  35     M2     c(25, 35)

这是不对的。

另外,我想避免每次计算时都使用as.character。有什么建议?感谢。

2 个答案:

答案 0 :(得分:0)

您可以通过dplyrmutate使用do。如果需要,您可以稍后cbind将此列放到原始数据框上。

基本上,这个想法首先是提取df$Choice所引用的列的索引,然后您可以在do中使用dplyr来创建一个新的数据框,并将其编入索引。

完整代码:

library(dplyr)

df <- data.frame(Name=c("Joy","Jane"),M1=c(10,40),M2=c(25,35),Choice=c("M1","M2"))
df$Choice <- as.character(df$Choice)
nm <- names(df)

df1 <- df %>% 
  rowwise %>%
  mutate(colIndex=which(nm == Choice)) %>%
  do(data.frame(Name=.$Name, Final=.[[.$colIndex]]))

输出

Source: local data frame [2 x 2]
Groups: <by row>

    Name Final
  <fctr> <dbl>
1    Joy    10
2   Jane    35

您只需使用df$Final <- df1$Final之类的内容即可获得您之后的结果。

> df$Final <- df1$Final
> df
  Name M1 M2 Choice Final
1  Joy 10 25     M1    10
2 Jane 40 35     M2    35

答案 1 :(得分:0)

为避免一再需要as.character(),请在stringasFactors中使用data.frame()参数:

df <- data.frame(Name=c("Joy","Jane"), M1=c(10,40), M2=c(25,35), Choice=c("M1","M2"),
                 stringsAsFactors = FALSE)

另外,考虑一个lapply解决方案:

df$Final <- unlist(lapply(1:nrow(df), function(i) df[i,df$Choice[i]]))