将值匹配到R中的对应列

时间:2018-09-19 17:21:10

标签: r dataframe key-value

我在R中有一个需要清洁的数据框。问题在于数据在值内(在引号内;它对应于列名)具有相应的列名。然后,我只想将数字值保留在:的右边。

这是原始数据框:

> df
      col1      col2     col3      col4      
 1  "4":50    "2":10    "1":0    "3":20        
 2   "2":5   "4":-50                                 
 3    NULL                                         
 4  "4":65    "3":45  "2":-15     "1":0

所需的输出:

 > new_df
      col1      col2     col3      col4      
 1       0        10       20        50        
 2       0         5        0       -50                                 
 3    NULL                                         
 4       0       -15       45        65

为方便起见,这是dput(df)的输出。

dput(df)
    structure(list(`1` = c("\"4\":50", "\"2\":5", "NULL", "\"4\":65"
), `2` = c("\"2\":10", "\"4\":-50", "", "\"3\":45"), `3` = c("\"1\":0", 
"", "", "\"2\":-15"), `4` = c("\"3\":20", "", "", "\"1\":0")), class = "data.frame", row.names = c(NA, 
-4L))

1 个答案:

答案 0 :(得分:0)

这是一个数据框,该数据框与该数据框尽可能接近。所有行都必须具有值或NA,因此第三行必须具有:

3 "NULL" ""    ""   ""   

引号和分隔符需要特别处理,因为使用read.table很难输入数据安排:

df <- read.table(text=' col1,      col2,     col3,      col4      
 1,  "4":50 ,   "2":10 ,  "1":0,    "3":20        
 2,   "2":5,   "4":-50                                 
 3,    NULL                                         
 4 , "4":65,    "3":45,  "2":-15,     "1":0', sep=",", header=TRUE,quote="\"",fill=TRUE,strip.white=TRUE)

现在可以分别在每一行上工作,并将值放置在键的位置:

我的第一次尝试是:

df2 <- apply(df, 1, function(x) if(x=="NULL"){ c("NULL",NA,NA,NA) } else 
                             { z <- rep(0,4)
                               for (i in x){
                                   z[as.numeric(sub( ":.+$", "", i))] <- sub("^.+:", "", i) }
                               return(z)})

如果从侧面看,这几乎是正确的。由于R以{列大”的形式返回apply的结果,因此您通常需要转置:

 df3 <- t(df2)
 df3
  [,1]   [,2]  [,3] [,4] 
1 "0"    "10"  "20" "50" 
2 "0"    "5"   "0"  "-50"
3 "NULL" NA    NA   NA   
4 "0"    "-15" "45" "65" 

@ Z.Springirth:请不要抱怨这些是字符值。您是在此输出中指定“ NULL”值的人。 “ NULL”不是合法的数值,并且数据框中的列必须属于同一类。因此,一列中的一个字符值会强制所有值成为字符。

这使您看起来很成功,但我警告您,列是因素而不是特征。除非您(单独)将其强制转换为数字,否则这些条目的行为不会像数字:

> as.data.frame(df3)
    V1   V2   V3   V4
1    0   10   20   50
2    0    5    0  -50
3 NULL <NA> <NA> <NA>
4    0  -15   45   65

如果您愿意放弃“ NULL”要求,则可以完成该过程:

> df4 <-  as.data.frame(df3,stringsAsFactors=FALSE) 
> df4[] <- lapply(df4, as.numeric)
Warning message:
In lapply(df4, as.numeric) : NAs introduced by coercion
> df4
  V1  V2 V3  V4
1  0  10 20  50
2  0   5  0 -50
3 NA  NA NA  NA
4  0 -15 45  65