R初学者在极其混乱的XLSX中苦苦挣扎
R Beginner struggling with extremely messy XLSX
我收到了一份 XLSX,其中包含我硕士论文的问卷调查数据。
受访者的问题和答案位于第二列的一行中。第一列包含日期。
第二列的数据格式如下:
"age":"52","height":"170","Gender":"Female",...and so on
我开始于:
test12 <- read_xlsx("Testdaten.xlsx")
library(splitstackshape)
test13 <- concat.split(data = test12, split.col= "age", sep =",")
然后我将问题和答案作为一列除以 ":"
。
例如column 1: "age":"52" and column2:"height":"170".
但是数据太乱了,有时年龄问答一栏有身高问答,有的问卷问答加倍。
我需要将问题作为变量,将答案作为观察结果。但我不知道如何到达那里。我可以先清理 excel 中的数据,但事实是列不是常量,例如年龄栏中的一些身高问题我认为没有机会这样做,因为我会定期获取新数据,格式相同。
这是一个数据示例:
小标题:5 x 2
partner.createdAtpartner.wphg.info<br>
<字符> <字符><br>
1 2019-11-09T12:13:11.099Z "{\"age_years\":\"50\",\"job_des\":\"unemployed\",\"height_cm\":\"170 \",\"Gender\":\"female\",\"born_in\":\"Italy\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"200000\""<br>
2 2019-11-01T06:43:22.581Z "{\"age_years\":\"34\",\"job_des\":\"self-employed\",\"height_cm\":\"158 \",\"Gender\":\"male\",\"born_in\":\"Germany\",\"Alcoholic\":\"true\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"10000\""<br>
3 2019-11-10T07:59:46.136Z "{\"age_years\":\"24\",\"height_cm\":\"187\",\"Gender\":\"male\",\"born_in\":\"England\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"3\",\"total_wealth\" :\"150000\""<br>
4 2019-11-11T13:01:48.488Z "{\"age_years\":\"59\",\"job_des\":\"employed\",\"height_cm\":\"167 \",\"Gender\":\"female\",\"born_in\":\"United States\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"2\",\"total_wealth\":\"1000000~
5 2019-11-08T14:54:26.654Z "{\"age_years\":\"36\",\"height_cm\":\"180\",\"born_in\":\"Germany\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"170000\",\"job_des\": \"employed\",\"Gender\":\"male\""
非常感谢您的宝贵时间!
您可以遍历每个条目,像您一样在 ,
处拆分。然后你可以再次遍历它们,在 :
.
处拆分
结果将是一堆 variable/value 对。这一切都可以堆叠完成。然后你只想回到列中。
数据
已根据您的编辑更新数据。
data <- tribble(~partner.createdAt, ~partner.wphg.info,
'2019-11-09T12:13:11.099Z', '{\"age_years\":\"50\",\"job_des\":\"unemployed\",\"height_cm\":\"170\",\"Gender\":\"female\",\"born_in\":\"Italy\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"200000\"',
'2019-11-01T06:43:22.581Z', '{\"age_years\":\"34\",\"job_des\":\"self-employed\",\"height_cm\":\"158\",\"Gender\":\"male\",\"born_in\":\"Germany\",\"Alcoholic\":\"true\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"10000\"',
'2019-11-10T07:59:46.136Z', '{\"age_years\":\"24\",\"height_cm\":\"187\",\"Gender\":\"male\",\"born_in\":\"England\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"150000\"',
'2019-11-11T13:01:48.488Z', '{\"age_years\":\"59\",\"job_des\":\"employed\",\"height_cm\":\"167\",\"Gender\":\"female\",\"born_in\":\"United States\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"2\",\"total_wealth\":\"1000000\"',
'2019-11-08T14:54:26.654Z', '{\"age_years\":\"36\",\"height_cm\":\"180\",\"born_in\":\"Germany\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"170000\",\"job_des\":\"employed\",\"Gender\":\"male\"')
图书馆
我们这里需要一些。或者你可以直接调用 tidyverse
.
library(stringr)
library(purrr)
library(dplyr)
library(tibble)
library(tidyr)
函数
此函数将为每个问题创建一个数据框(或 tibble)。第一列是日期,第二列是变量,第三列是值。
clean_record <- function(date, text) {
clean_records <- str_split(text, pattern = ",", simplify = TRUE) %>%
str_remove_all(pattern = "\\"") %>% # remove double quote
str_remove_all(pattern = "\{|\}") %>% # remove curly brackets
str_split(pattern = ":", simplify = TRUE)
tibble(date = as.Date(date), variable = clean_records[,1], value = clean_records[,2])
}
迭代
现在我们使用 purrr
中的 pmap_dfr
遍历行,输出每行一个名为 record
.
的 id 变量
这将按照函数中的描述堆叠数据。 mutate()
行将所有变量名转换为小写。 distinct()
行将过滤掉完全重复的行。
然后我们所做的只是在 variable
列上进行透视。当然,将 data
替换为您命名的数据框。
data_clean <- pmap_dfr(data, ~ clean_record(..1, ..2), .id = "record") %>%
mutate(variable = tolower(variable)) %>%
distinct() %>%
pivot_wider(names_from = variable, values_from = value)
结果
结果是这样的。请注意我是如何重新排序某些列的,但它仍然有效。您可能还没有完成。所有列现在都是 character
类型。您需要找出每个所需的类型并进行转换。
# A tibble: 5 x 10
record date age_years job_des height_cm gender born_in alcoholic knowledge_selfass total_wealth
<chr> <date> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 1 2019-11-09 50 unemployed 170 female Italy false 5 200000
2 2 2019-11-01 34 self-employed 158 male Germany true 3 10000
3 3 2019-11-10 24 NA 187 male England false 3 150000
4 4 2019-11-11 59 employed 167 female United States false 2 1000000
5 5 2019-11-08 36 employed 180 male Germany false 5 170000
例如,将age_years
转换为数字。
data_clean %>%
mutate(age_years = as.numeric(age_years))
我相信您可能 运行 从事其他事情,但这应该是一个开始。
我收到了一份 XLSX,其中包含我硕士论文的问卷调查数据。 受访者的问题和答案位于第二列的一行中。第一列包含日期。
第二列的数据格式如下:
"age":"52","height":"170","Gender":"Female",...and so on
我开始于:
test12 <- read_xlsx("Testdaten.xlsx")
library(splitstackshape)
test13 <- concat.split(data = test12, split.col= "age", sep =",")
然后我将问题和答案作为一列除以 ":"
。
例如column 1: "age":"52" and column2:"height":"170".
但是数据太乱了,有时年龄问答一栏有身高问答,有的问卷问答加倍。
我需要将问题作为变量,将答案作为观察结果。但我不知道如何到达那里。我可以先清理 excel 中的数据,但事实是列不是常量,例如年龄栏中的一些身高问题我认为没有机会这样做,因为我会定期获取新数据,格式相同。
这是一个数据示例:
小标题:5 x 2
partner.createdAtpartner.wphg.info<br>
<字符> <字符><br>
1 2019-11-09T12:13:11.099Z "{\"age_years\":\"50\",\"job_des\":\"unemployed\",\"height_cm\":\"170 \",\"Gender\":\"female\",\"born_in\":\"Italy\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"200000\""<br>
2 2019-11-01T06:43:22.581Z "{\"age_years\":\"34\",\"job_des\":\"self-employed\",\"height_cm\":\"158 \",\"Gender\":\"male\",\"born_in\":\"Germany\",\"Alcoholic\":\"true\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"10000\""<br>
3 2019-11-10T07:59:46.136Z "{\"age_years\":\"24\",\"height_cm\":\"187\",\"Gender\":\"male\",\"born_in\":\"England\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"3\",\"total_wealth\" :\"150000\""<br>
4 2019-11-11T13:01:48.488Z "{\"age_years\":\"59\",\"job_des\":\"employed\",\"height_cm\":\"167 \",\"Gender\":\"female\",\"born_in\":\"United States\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"2\",\"total_wealth\":\"1000000~
5 2019-11-08T14:54:26.654Z "{\"age_years\":\"36\",\"height_cm\":\"180\",\"born_in\":\"Germany\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"170000\",\"job_des\": \"employed\",\"Gender\":\"male\""
非常感谢您的宝贵时间!
您可以遍历每个条目,像您一样在 ,
处拆分。然后你可以再次遍历它们,在 :
.
结果将是一堆 variable/value 对。这一切都可以堆叠完成。然后你只想回到列中。
数据
已根据您的编辑更新数据。
data <- tribble(~partner.createdAt, ~partner.wphg.info,
'2019-11-09T12:13:11.099Z', '{\"age_years\":\"50\",\"job_des\":\"unemployed\",\"height_cm\":\"170\",\"Gender\":\"female\",\"born_in\":\"Italy\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"200000\"',
'2019-11-01T06:43:22.581Z', '{\"age_years\":\"34\",\"job_des\":\"self-employed\",\"height_cm\":\"158\",\"Gender\":\"male\",\"born_in\":\"Germany\",\"Alcoholic\":\"true\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"10000\"',
'2019-11-10T07:59:46.136Z', '{\"age_years\":\"24\",\"height_cm\":\"187\",\"Gender\":\"male\",\"born_in\":\"England\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"3\",\"total_wealth\":\"150000\"',
'2019-11-11T13:01:48.488Z', '{\"age_years\":\"59\",\"job_des\":\"employed\",\"height_cm\":\"167\",\"Gender\":\"female\",\"born_in\":\"United States\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"2\",\"total_wealth\":\"1000000\"',
'2019-11-08T14:54:26.654Z', '{\"age_years\":\"36\",\"height_cm\":\"180\",\"born_in\":\"Germany\",\"Alcoholic\":\"false\",\"knowledge_selfass\":\"5\",\"total_wealth\":\"170000\",\"job_des\":\"employed\",\"Gender\":\"male\"')
图书馆
我们这里需要一些。或者你可以直接调用 tidyverse
.
library(stringr)
library(purrr)
library(dplyr)
library(tibble)
library(tidyr)
函数
此函数将为每个问题创建一个数据框(或 tibble)。第一列是日期,第二列是变量,第三列是值。
clean_record <- function(date, text) {
clean_records <- str_split(text, pattern = ",", simplify = TRUE) %>%
str_remove_all(pattern = "\\"") %>% # remove double quote
str_remove_all(pattern = "\{|\}") %>% # remove curly brackets
str_split(pattern = ":", simplify = TRUE)
tibble(date = as.Date(date), variable = clean_records[,1], value = clean_records[,2])
}
迭代
现在我们使用 purrr
中的 pmap_dfr
遍历行,输出每行一个名为 record
.
这将按照函数中的描述堆叠数据。 mutate()
行将所有变量名转换为小写。 distinct()
行将过滤掉完全重复的行。
然后我们所做的只是在 variable
列上进行透视。当然,将 data
替换为您命名的数据框。
data_clean <- pmap_dfr(data, ~ clean_record(..1, ..2), .id = "record") %>%
mutate(variable = tolower(variable)) %>%
distinct() %>%
pivot_wider(names_from = variable, values_from = value)
结果
结果是这样的。请注意我是如何重新排序某些列的,但它仍然有效。您可能还没有完成。所有列现在都是 character
类型。您需要找出每个所需的类型并进行转换。
# A tibble: 5 x 10
record date age_years job_des height_cm gender born_in alcoholic knowledge_selfass total_wealth
<chr> <date> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 1 2019-11-09 50 unemployed 170 female Italy false 5 200000
2 2 2019-11-01 34 self-employed 158 male Germany true 3 10000
3 3 2019-11-10 24 NA 187 male England false 3 150000
4 4 2019-11-11 59 employed 167 female United States false 2 1000000
5 5 2019-11-08 36 employed 180 male Germany false 5 170000
例如,将age_years
转换为数字。
data_clean %>%
mutate(age_years = as.numeric(age_years))
我相信您可能 运行 从事其他事情,但这应该是一个开始。