【问题标题】:Need to update a DataFrame in R from another DataFrame, colnames of one dataframe matches contents of other dataframe需要从另一个 DataFrame 更新 R 中的 DataFrame,一个 DataFrame 的 colnames 与另一个 DataFrame 的内容匹配
【发布时间】:2020-08-18 01:25:58
【问题描述】:

这是我在这个神奇网站上的第一个问题。请原谅我的无知。

我正在尝试在 R 中整理数据框以进行数据分析。

我的数据框 df1` 看起来像-

| id |  features                            

| 1 |   Window, Door, House, Curtains       |

| 2 |   Window, AirConditioner, GasStove    |

| 3 |   GasStove, Parking, Curtains         |

| 4 |   Curtains, Cable, Window             |

我已经通过拆分文本成功地创建了另一个数据框-

s <- strsplit(df1$features, split = ",")
df2  <- data.frame(id = rep(df1$id, sapply(s, length)), features = unique(unlist(s)))

现在,df2 看起来像 -

id| features

|1| Window

|1| Door

|1| House

|1| Curtains

|2| Window

|2| AirConditioner

|2| GasStove

|3| GasStove

|3| Parking

|3| Curtains

|4| Curtains

|4| Cable

|4| Window

我还在 df1 数据框中创建了所有这些 UNIQUE 列,例如 - Window、Door、House 等。

我希望我的最终数据框 df3 如下所示 -

|ID|Window| Door    |House  |Curtain    |AirConditioner| GasStove|  Parking |Cable|

 |1|    1   |1          |1      |1          |0             |0        |0         |0

|2| 1   |0  |0  |0  |1      |1  |0  |0

|3| 0   |0  |0  |1  |0      |1  |1  |0

|4| 1   |0  |0  |1  |0      |0  |0  |1

这些值可能是 True (1) 或 False (0)。

简而言之,我需要的是,df2 的特征列包含 df3 的列的“名称”,这些列需要填充 True/False(或 1/0)。

尽管尝试了很多次,我还是无法制作这个。

非常感谢您的意见。

我可以在 Python 中使用 chain.from_iterable 以上,但在 R 中实现它时遇到了麻烦。

【问题讨论】:

  • 您好 Vinay,欢迎来到 SO!如果您使用dput(df1) 添加数据,其他人会更容易提供帮助。
  • 感谢您的建议!下次我会做的。

标签: r dataframe


【解决方案1】:

如果您愿意接受使用tidyverse 的解决方案

library(tidyverse)

df1 %>% 
  separate_rows(features, sep = ', ') %>% 
  mutate(logical = 1) %>% 
  pivot_wider(names_from = features, values_from = logical) %>% 
  replace(is.na(.), 0)


#> # A tibble: 4 x 9
#>      id Window  Door House Curtains AirConditioner GasStove Parking Cable
#>   <dbl>  <dbl> <dbl> <dbl>    <dbl>          <dbl>    <dbl>   <dbl> <dbl>
#> 1     1      1     1     1        1              0        0       0     0
#> 2     2      1     0     0        0              1        1       0     0
#> 3     3      0     0     0        1              0        1       1     0
#> 4     4      1     0     0        1              0        0       0     1

数据

df1 <- structure(list(id = c(1, 2, 3, 4), features = c("Window, Door, House, Curtains", 
                                                "Window, AirConditioner, GasStove", "GasStove, Parking, Curtains", 
                                                "Curtains, Cable, Window")), class = "data.frame", row.names = c(NA, 
                                                                                                                 -4L))

编辑:上面的代码跳过了df2,但如果您更愿意在此处生成它,这是一种解决方案。请注意,我从df2 中的features = unlist(s) 中删除了unique

s <- strsplit(df1$features, split = ", ")  
df2  <- data.frame(id = rep(df1$id, sapply(s, length)), features = unlist(s))

df3 <- df2 %>% 
  mutate(logical = 1) %>% 
  pivot_wider(names_from = features, values_from = logical) %>% 
  replace(is.na(.), 0)

【讨论】:

  • 感谢您的宝贵时间和意见。当我运行您上面建议的代码时,它会生成错误 - 错误:由于失去一般性,无法从 转换为 >。
  • 我刚刚重新运行,它可以在我的机器上运行(R v4.0.2 和 Tidyverse 1.3.0)。您是否按照我的建议尝试了df1?作为猜测,您的df1 可能与我的不同。
【解决方案2】:

这是一个基本的 R 选项

df3 <- reshape(
  cbind(df2, X = 1),
  direction = "wide",
  idvar = "id",
  timevar = "features"
)
df3 <- replace(df3,is.na(df3),0)

给了

   id X.Window X.Door X.House X.Curtains X.AirConditioner X.GasStove X.Parking
1   1        1      1       1          1                0          0         0
5   2        1      0       0          0                1          1         0
8   3        0      0       0          1                0          1         1
11  4        1      0       0          1                0          0         0
   X.Cable
1        0
5        0
8        0
11       1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    相关资源
    最近更新 更多