【问题标题】:lists match with dataframe列表与数据框匹配
【发布时间】:2017-12-08 14:47:56
【问题描述】:

我想用数据框匹配列表

> lists
    [[1]]
    [1] "SURFSKINTEMP=6" "MODIS_LST=1"   

    [[2]]
    [1] "TOTCO=13"    "MODIS_LST=1"

    [[3]]
    [1] "TOTCO=6"     "MODIS_LST=1"

    [[4]]
    [1] "TOTO3=15"    "MODIS_LST=1"

    [[5]]
    [1] "TOTH2OVAP=6" "MODIS_LST=1"

    [[6]]
    [1] "TOTH2OVAP=1" "MODIS_LST=1"

和测试数据框

 > test
      LONGITUDE LATITUDE DATE_START   DATE_END FLAG SURFSKINTEMP SURFAIRTEMP TOTH2OVAP TOTO3 TOTCO TOTCH4 OLR_ARIS CLROLR_ARIS OLR_NOAA MODIS_LST
    1     118.5    -11.5 2014-12-30 2015-01-06    2            6           6         6    16    13     13       10          10       10         1

在上面的例子中。 data.frame 匹配 3 个列表

[1] "SURFSKINTEMP=6" "MODIS_LST=1" 
[1] "TOTCO=13"    "MODIS_LST=1"  
[1] "TOTH2OVAP=6" "MODIS_LST=1"

所以匹配数是3,匹配率是3/6 = 50%。

我希望会添加两列(MATCH_COUNT MATCH_RATIO),例如:

  LONGITUDE LATITUDE DATE_START   DATE_END FLAG SURFSKINTEMP SURFAIRTEMP TOTH2OVAP TOTO3 TOTCO TOTCH4  OLR_ARIS CLROLR_ARIS OLR_NOAA MODIS_LST  MATCH_COUNT  MATCH_RATIO          
1     118.5    -11.5 2014-12-30 2015-01-06    2            6           6         6    16    13     13        10          10       10         1            3          0.5

我使用的列表和测试数据框是:

lists <- list(c("SURFSKINTEMP=6", "MODIS_LST=1"), c("TOTCO=13", "MODIS_LST=1"
), c("TOTCO=6", "MODIS_LST=1"), c("TOTO3=15", "MODIS_LST=1"), 
    c("TOTH2OVAP=6", "MODIS_LST=1"), c("TOTH2OVAP=1", "MODIS_LST=1"
    ))



test <- structure(list(LONGITUDE = 118.5, LATITUDE = -11.5, DATE_START = structure(1419897600, class = c("POSIXct", 
"POSIXt")), DATE_END = structure(1420502400, class = c("POSIXct", 
"POSIXt")), FLAG = 2, SURFSKINTEMP = 6L, SURFAIRTEMP = 6L, TOTH2OVAP = 6L, 
    TOTO3 = 16L, TOTCO = 13L, TOTCH4 = 13L, OLR_ARIS = 10L, CLROLR_ARIS = 10L, 
    OLR_NOAA = 10L, MODIS_LST = 1L), .Names = c("LONGITUDE", 
"LATITUDE", "DATE_START", "DATE_END", "FLAG", "SURFSKINTEMP", 
"SURFAIRTEMP", "TOTH2OVAP", "TOTO3", "TOTCO", "TOTCH4", "OLR_ARIS", 
"CLROLR_ARIS", "OLR_NOAA", "MODIS_LST"), row.names = 1L, class = "data.frame")

如何实现,谢谢

对于多行

> test1
  LONGITUDE LATITUDE DATE_START   DATE_END FLAG SURFSKINTEMP SURFAIRTEMP TOTH2OVAP TOTO3 TOTCO TOTCH4 OLR_ARIS CLROLR_ARIS OLR_NOAA MODIS_LST
1     118.5    -11.5 2014-12-30 2015-01-06    2            6           6         6    16    13     13       10          10       10         1
2     118.5    -11.5 2014-12-31 2015-01-07    2            1           6         1    16     6     14        4           4       10         1
3     118.5    -11.5 2015-01-01 2015-01-08    2           16           6        17    16     8      6        4           4       10         2

我的期望是

  LONGITUDE LATITUDE DATE_START   DATE_END FLAG SURFSKINTEMP SURFAIRTEMP TOTH2OVAP TOTO3 TOTCO TOTCH4 OLR_ARIS CLROLR_ARIS OLR_NOAA MODIS_LST  MATCH_COUNT  MATCH_RATIO
1     118.5    -11.5 2014-12-30 2015-01-06    2            6           6         6    16    13     13       10          10       10         1            3          0.5
2     118.5    -11.5 2014-12-31 2015-01-07    2            1           6         1    16     6     14        4           4       10         1            2        0.333
3     118.5    -11.5 2015-01-01 2015-01-08    2           16           6        17    16     8      6        4           4       10         2            0            0

这里用到的数据是

test1 <- structure(list(LONGITUDE = c(118.5, 118.5, 118.5), LATITUDE = c(-11.5,                                                            
-11.5, -11.5), DATE_START = structure(c(1419897600, 1419984000,                                                                   
1420070400), class = c("POSIXct", "POSIXt")), DATE_END = structure(c(1420502400,                                                 
1420588800, 1420675200), class = c("POSIXct", "POSIXt")), FLAG = c(2,                                                             
2, 2), SURFSKINTEMP = c(6L, 1L, 16L), SURFAIRTEMP = c(6L, 6L,                     
6L), TOTH2OVAP = c(6L, 1L, 17L), TOTO3 = c(16L, 16L, 16L), TOTCO = c(13L,         
6L, 8L), TOTCH4 = c(13L, 14L, 6L), OLR_ARIS = c(10L, 4L, 4L),                     
    CLROLR_ARIS = c(10L, 4L, 4L), OLR_NOAA = c(10L, 10L, 10L),                   
    MODIS_LST = c(1L, 1L, 2L)), .Names = c("LONGITUDE", "LATITUDE",              
"DATE_START", "DATE_END", "FLAG", "SURFSKINTEMP", "SURFAIRTEMP",                 
"TOTH2OVAP", "TOTO3", "TOTCO", "TOTCH4", "OLR_ARIS", "CLROLR_ARIS",              
"OLR_NOAA", "MODIS_LST"), row.names = c(NA, 3L), class = "data.frame") 

【问题讨论】:

    标签: r list dataframe


    【解决方案1】:

    我们可以paste'test'的列名与'test'的单行,检查all每个list元素中的元素是否存在于pasted向量中以获得逻辑向量。通过获取逻辑vectorsummean 来创建列

    v1 <- paste(names(test), unlist(test), sep="=")
    i1 <- sapply(lists, function(x) all(x %in% v1))
    test[c('MATCH_COUNT', 'MATCH_RATIO')] <- list(sum(i1), mean(i1))
    test
    #  LONGITUDE LATITUDE          DATE_START            DATE_END FLAG SURFSKINTEMP SURFAIRTEMP TOTH2OVAP TOTO3 TOTCO TOTCH4 OLR_ARIS CLROLR_ARIS OLR_NOAA MODIS_LST
    #1     118.5    -11.5 2014-12-30 05:30:00 2015-01-06 05:30:00    2            6           6         6    16    13     13       10          10       10         1
    #  MATCH_COUNT MATCH_RATIO
    #1           3         0.5
    

    如果数据集“测试”的行数超过 1 行,则

    m1 <- matrix(paste(names(test1)[col(test1)], unlist(test1), sep="="), ncol = ncol(test1))
    i2 <- sapply(lists, function(x) apply(m1, 1, function(y) all(x %in% y)))
    test1[c('MATCH_COUNT', 'MATCH_RATIO')] <- list(rowSums(i2), rowMeans(i2))
    

    【讨论】:

    • 谢谢,如果我的data.frame测试多于1行,需要逐行统计匹配,多行怎么处理?
    • @Pan 在这种情况下,您可能需要逐行粘贴,即apply(test, 1, function(x) paste(names(x), x, sep="=")) 左右
    • i1
    • 你能告诉我如何在我的情况下按行执行@akrun 在这个语句'i1
    • @Pan 你能再更新一行数据吗?我需要测试一下
    猜你喜欢
    • 2016-08-26
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    相关资源
    最近更新 更多